1 /* SHA256-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
11 #ifdef PHP_WIN32
12 # define __alignof__ __alignof
13 #else
14 # ifndef HAVE_ALIGNOF
15 # include <stddef.h>
16 # define __alignof__(type) offsetof (struct { char c; type member;}, member)
17 # endif
18 #endif
19
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #ifdef PHP_WIN32
24 # include <string.h>
25 #else
26 # include <sys/param.h>
27 # include <sys/types.h>
28 # include <string.h>
29 #endif
30
__php_stpncpy(char * dst,const char * src,size_t len)31 char * __php_stpncpy(char *dst, const char *src, size_t len)
32 {
33 size_t n = strlen(src);
34 if (n > len) {
35 n = len;
36 }
37 return strncpy(dst, src, len) + n;
38 }
39
__php_mempcpy(void * dst,const void * src,size_t len)40 void * __php_mempcpy(void * dst, const void * src, size_t len)
41 {
42 return (((char *)memcpy(dst, src, len)) + len);
43 }
44
45 #ifndef MIN
46 # define MIN(a, b) (((a) < (b)) ? (a) : (b))
47 #endif
48 #ifndef MAX
49 # define MAX(a, b) (((a) > (b)) ? (a) : (b))
50 #endif
51
52 /* Structure to save state of computation between the single steps. */
53 struct sha256_ctx {
54 uint32_t H[8];
55
56 uint32_t total[2];
57 uint32_t buflen;
58 char buffer[128]; /* NB: always correctly aligned for uint32_t. */
59 };
60
61 #if defined(PHP_WIN32) || (!defined(WORDS_BIGENDIAN))
62 # define SWAP(n) \
63 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
64 #else
65 # define SWAP(n) (n)
66 #endif
67
68 /* This array contains the bytes used to pad the buffer to the next
69 64-byte boundary. (FIPS 180-2:5.1.1) */
70 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
71
72
73 /* Constants for SHA256 from FIPS 180-2:4.2.2. */
74 static const uint32_t K[64] = {
75 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
76 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
77 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
78 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
79 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
80 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
81 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
82 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
83 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
84 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
85 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
86 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
87 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
88 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
89 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
90 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
91 };
92
93
94 /* Process LEN bytes of BUFFER, accumulating context into CTX.
95 It is assumed that LEN % 64 == 0. */
sha256_process_block(const void * buffer,size_t len,struct sha256_ctx * ctx)96 static void sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx) {
97 const uint32_t *words = buffer;
98 size_t nwords = len / sizeof (uint32_t);
99 unsigned int t;
100
101 uint32_t a = ctx->H[0];
102 uint32_t b = ctx->H[1];
103 uint32_t c = ctx->H[2];
104 uint32_t d = ctx->H[3];
105 uint32_t e = ctx->H[4];
106 uint32_t f = ctx->H[5];
107 uint32_t g = ctx->H[6];
108 uint32_t h = ctx->H[7];
109
110 /* First increment the byte count. FIPS 180-2 specifies the possible
111 length of the file up to 2^64 bits. Here we only compute the
112 number of bytes. Do a double word increment. */
113 ctx->total[0] += (uint32_t)len;
114 if (ctx->total[0] < len) {
115 ++ctx->total[1];
116 }
117
118 /* Process all bytes in the buffer with 64 bytes in each round of
119 the loop. */
120 while (nwords > 0) {
121 uint32_t W[64];
122 uint32_t a_save = a;
123 uint32_t b_save = b;
124 uint32_t c_save = c;
125 uint32_t d_save = d;
126 uint32_t e_save = e;
127 uint32_t f_save = f;
128 uint32_t g_save = g;
129 uint32_t h_save = h;
130
131 /* Operators defined in FIPS 180-2:4.1.2. */
132 #define Ch(x, y, z) ((x & y) ^ (~x & z))
133 #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
134 #define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22))
135 #define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25))
136 #define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3))
137 #define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10))
138
139 /* It is unfortunate that C does not provide an operator for
140 cyclic rotation. Hope the C compiler is smart enough. */
141 #define CYCLIC(w, s) ((w >> s) | (w << (32 - s)))
142
143 /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */
144 for (t = 0; t < 16; ++t) {
145 W[t] = SWAP (*words);
146 ++words;
147 }
148 for (t = 16; t < 64; ++t)
149 W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
150
151 /* The actual computation according to FIPS 180-2:6.2.2 step 3. */
152 for (t = 0; t < 64; ++t) {
153 uint32_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
154 uint32_t T2 = S0 (a) + Maj (a, b, c);
155 h = g;
156 g = f;
157 f = e;
158 e = d + T1;
159 d = c;
160 c = b;
161 b = a;
162 a = T1 + T2;
163 }
164
165 /* Add the starting values of the context according to FIPS 180-2:6.2.2
166 step 4. */
167 a += a_save;
168 b += b_save;
169 c += c_save;
170 d += d_save;
171 e += e_save;
172 f += f_save;
173 g += g_save;
174 h += h_save;
175
176 /* Prepare for the next round. */
177 nwords -= 16;
178 }
179
180 /* Put checksum in context given as argument. */
181 ctx->H[0] = a;
182 ctx->H[1] = b;
183 ctx->H[2] = c;
184 ctx->H[3] = d;
185 ctx->H[4] = e;
186 ctx->H[5] = f;
187 ctx->H[6] = g;
188 ctx->H[7] = h;
189 }
190
191
192 /* Initialize structure containing state of computation.
193 (FIPS 180-2:5.3.2) */
sha256_init_ctx(struct sha256_ctx * ctx)194 static void sha256_init_ctx(struct sha256_ctx *ctx) {
195 ctx->H[0] = 0x6a09e667;
196 ctx->H[1] = 0xbb67ae85;
197 ctx->H[2] = 0x3c6ef372;
198 ctx->H[3] = 0xa54ff53a;
199 ctx->H[4] = 0x510e527f;
200 ctx->H[5] = 0x9b05688c;
201 ctx->H[6] = 0x1f83d9ab;
202 ctx->H[7] = 0x5be0cd19;
203
204 ctx->total[0] = ctx->total[1] = 0;
205 ctx->buflen = 0;
206 }
207
208
209 /* Process the remaining bytes in the internal buffer and the usual
210 prolog according to the standard and write the result to RESBUF.
211
212 IMPORTANT: On some systems it is required that RESBUF is correctly
213 aligned for a 32 bits value. */
sha256_finish_ctx(struct sha256_ctx * ctx,void * resbuf)214 static void * sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) {
215 /* Take yet unprocessed bytes into account. */
216 uint32_t bytes = ctx->buflen;
217 size_t pad;
218 unsigned int i;
219
220 /* Now count remaining bytes. */
221 ctx->total[0] += bytes;
222 if (ctx->total[0] < bytes) {
223 ++ctx->total[1];
224 }
225
226 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
227 memcpy(&ctx->buffer[bytes], fillbuf, pad);
228
229 /* Put the 64-bit file length in *bits* at the end of the buffer. */
230 *(uint32_t *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3);
231 *(uint32_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) |
232 (ctx->total[0] >> 29));
233
234 /* Process last bytes. */
235 sha256_process_block(ctx->buffer, bytes + pad + 8, ctx);
236
237 /* Put result from CTX in first 32 bytes following RESBUF. */
238 for (i = 0; i < 8; ++i) {
239 ((uint32_t *) resbuf)[i] = SWAP(ctx->H[i]);
240 }
241
242 return resbuf;
243 }
244
245
sha256_process_bytes(const void * buffer,size_t len,struct sha256_ctx * ctx)246 static void sha256_process_bytes(const void *buffer, size_t len, struct sha256_ctx *ctx) {
247 /* When we already have some bits in our internal buffer concatenate
248 both inputs first. */
249 if (ctx->buflen != 0) {
250 size_t left_over = ctx->buflen;
251 size_t add = 128 - left_over > len ? len : 128 - left_over;
252
253 memcpy(&ctx->buffer[left_over], buffer, add);
254 ctx->buflen += (uint32_t)add;
255
256 if (ctx->buflen > 64) {
257 sha256_process_block(ctx->buffer, ctx->buflen & ~63, ctx);
258 ctx->buflen &= 63;
259 /* The regions in the following copy operation cannot overlap. */
260 memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63], ctx->buflen);
261 }
262
263 buffer = (const char *) buffer + add;
264 len -= add;
265 }
266
267 /* Process available complete blocks. */
268 if (len >= 64) {
269 /* To check alignment gcc has an appropriate operator. Other
270 compilers don't. */
271 #if __GNUC__ >= 2
272 # define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0)
273 #else
274 # define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0)
275 #endif
276 if (UNALIGNED_P (buffer))
277 while (len > 64) {
278 sha256_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx);
279 buffer = (const char *) buffer + 64;
280 len -= 64;
281 } else {
282 sha256_process_block(buffer, len & ~63, ctx);
283 buffer = (const char *) buffer + (len & ~63);
284 len &= 63;
285 }
286 }
287
288 /* Move remaining bytes into internal buffer. */
289 if (len > 0) {
290 size_t left_over = ctx->buflen;
291
292 memcpy(&ctx->buffer[left_over], buffer, len);
293 left_over += len;
294 if (left_over >= 64) {
295 sha256_process_block(ctx->buffer, 64, ctx);
296 left_over -= 64;
297 memcpy(ctx->buffer, &ctx->buffer[64], left_over);
298 }
299 ctx->buflen = (uint32_t)left_over;
300 }
301 }
302
303
304 /* Define our magic string to mark salt for SHA256 "encryption"
305 replacement. */
306 static const char sha256_salt_prefix[] = "$5$";
307
308 /* Prefix for optional rounds specification. */
309 static const char sha256_rounds_prefix[] = "rounds=";
310
311 /* Maximum salt string length. */
312 #define SALT_LEN_MAX 16
313 /* Default number of rounds if not explicitly specified. */
314 #define ROUNDS_DEFAULT 5000
315 /* Minimum number of rounds. */
316 #define ROUNDS_MIN 1000
317 /* Maximum number of rounds. */
318 #define ROUNDS_MAX 999999999
319
320 /* Table with characters for base64 transformation. */
321 static const char b64t[64] =
322 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
323
php_sha256_crypt_r(const char * key,const char * salt,char * buffer,int buflen)324 char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int buflen)
325 {
326 #ifdef PHP_WIN32
327 ZEND_SET_ALIGNED(32, unsigned char alt_result[32]);
328 ZEND_SET_ALIGNED(32, unsigned char temp_result[32]);
329 #else
330 ZEND_SET_ALIGNED(__alignof__ (uint32_t), unsigned char alt_result[32]);
331 ZEND_SET_ALIGNED(__alignof__ (uint32_t), unsigned char temp_result[32]);
332 #endif
333
334 struct sha256_ctx ctx;
335 struct sha256_ctx alt_ctx;
336 size_t salt_len;
337 size_t key_len;
338 size_t cnt;
339 char *cp;
340 char *copied_key = NULL;
341 char *copied_salt = NULL;
342 char *p_bytes;
343 char *s_bytes;
344 /* Default number of rounds. */
345 size_t rounds = ROUNDS_DEFAULT;
346 bool rounds_custom = 0;
347
348 /* Find beginning of salt string. The prefix should normally always
349 be present. Just in case it is not. */
350 if (strncmp(sha256_salt_prefix, salt, sizeof(sha256_salt_prefix) - 1) == 0) {
351 /* Skip salt prefix. */
352 salt += sizeof(sha256_salt_prefix) - 1;
353 }
354
355 if (strncmp(salt, sha256_rounds_prefix, sizeof(sha256_rounds_prefix) - 1) == 0) {
356 const char *num = salt + sizeof(sha256_rounds_prefix) - 1;
357 char *endp;
358 zend_ulong srounds = ZEND_STRTOUL(num, &endp, 10);
359 if (*endp == '$') {
360 salt = endp + 1;
361 if (srounds < ROUNDS_MIN || srounds > ROUNDS_MAX) {
362 return NULL;
363 }
364
365 rounds = srounds;
366 rounds_custom = 1;
367 }
368 }
369
370 salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
371 key_len = strlen(key);
372 char *tmp_key = NULL;
373 ALLOCA_FLAG(use_heap_key);
374 char *tmp_salt = NULL;
375 ALLOCA_FLAG(use_heap_salt);
376
377 SET_ALLOCA_FLAG(use_heap_key);
378 SET_ALLOCA_FLAG(use_heap_salt);
379
380 if ((uintptr_t)key % __alignof__ (uint32_t) != 0) {
381 tmp_key = (char *) do_alloca(key_len + __alignof__(uint32_t), use_heap_key);
382 key = copied_key = memcpy(tmp_key + __alignof__(uint32_t) - (uintptr_t)tmp_key % __alignof__(uint32_t), key, key_len);
383 }
384
385 if ((uintptr_t)salt % __alignof__(uint32_t) != 0) {
386 tmp_salt = (char *) do_alloca(salt_len + 1 + __alignof__(uint32_t), use_heap_salt);
387 salt = copied_salt =
388 memcpy(tmp_salt + __alignof__(uint32_t) - (uintptr_t)tmp_salt % __alignof__ (uint32_t), salt, salt_len);
389 copied_salt[salt_len] = 0;
390 }
391
392 /* Prepare for the real work. */
393 sha256_init_ctx(&ctx);
394
395 /* Add the key string. */
396 sha256_process_bytes(key, key_len, &ctx);
397
398 /* The last part is the salt string. This must be at most 16
399 characters and it ends at the first `$' character (for
400 compatibility with existing implementations). */
401 sha256_process_bytes(salt, salt_len, &ctx);
402
403
404 /* Compute alternate SHA256 sum with input KEY, SALT, and KEY. The
405 final result will be added to the first context. */
406 sha256_init_ctx(&alt_ctx);
407
408 /* Add key. */
409 sha256_process_bytes(key, key_len, &alt_ctx);
410
411 /* Add salt. */
412 sha256_process_bytes(salt, salt_len, &alt_ctx);
413
414 /* Add key again. */
415 sha256_process_bytes(key, key_len, &alt_ctx);
416
417 /* Now get result of this (32 bytes) and add it to the other
418 context. */
419 sha256_finish_ctx(&alt_ctx, alt_result);
420
421 /* Add for any character in the key one byte of the alternate sum. */
422 for (cnt = key_len; cnt > 32; cnt -= 32) {
423 sha256_process_bytes(alt_result, 32, &ctx);
424 }
425 sha256_process_bytes(alt_result, cnt, &ctx);
426
427 /* Take the binary representation of the length of the key and for every
428 1 add the alternate sum, for every 0 the key. */
429 for (cnt = key_len; cnt > 0; cnt >>= 1) {
430 if ((cnt & 1) != 0) {
431 sha256_process_bytes(alt_result, 32, &ctx);
432 } else {
433 sha256_process_bytes(key, key_len, &ctx);
434 }
435 }
436
437 /* Create intermediate result. */
438 sha256_finish_ctx(&ctx, alt_result);
439
440 /* Start computation of P byte sequence. */
441 sha256_init_ctx(&alt_ctx);
442
443 /* For every character in the password add the entire password. */
444 for (cnt = 0; cnt < key_len; ++cnt) {
445 sha256_process_bytes(key, key_len, &alt_ctx);
446 }
447
448 /* Finish the digest. */
449 sha256_finish_ctx(&alt_ctx, temp_result);
450
451 /* Create byte sequence P. */
452 ALLOCA_FLAG(use_heap_p_bytes);
453 cp = p_bytes = do_alloca(key_len, use_heap_p_bytes);
454 for (cnt = key_len; cnt >= 32; cnt -= 32) {
455 cp = __php_mempcpy((void *)cp, (const void *)temp_result, 32);
456 }
457 memcpy(cp, temp_result, cnt);
458
459 /* Start computation of S byte sequence. */
460 sha256_init_ctx(&alt_ctx);
461
462 /* For every character in the password add the entire password. */
463 for (cnt = 0; cnt < (size_t) (16 + alt_result[0]); ++cnt) {
464 sha256_process_bytes(salt, salt_len, &alt_ctx);
465 }
466
467 /* Finish the digest. */
468 sha256_finish_ctx(&alt_ctx, temp_result);
469
470 /* Create byte sequence S. */
471 ALLOCA_FLAG(use_heap_s_bytes);
472 cp = s_bytes = do_alloca(salt_len, use_heap_s_bytes);
473 for (cnt = salt_len; cnt >= 32; cnt -= 32) {
474 cp = __php_mempcpy(cp, temp_result, 32);
475 }
476 memcpy(cp, temp_result, cnt);
477
478 /* Repeatedly run the collected hash value through SHA256 to burn
479 CPU cycles. */
480 for (cnt = 0; cnt < rounds; ++cnt) {
481 /* New context. */
482 sha256_init_ctx(&ctx);
483
484 /* Add key or last result. */
485 if ((cnt & 1) != 0) {
486 sha256_process_bytes(p_bytes, key_len, &ctx);
487 } else {
488 sha256_process_bytes(alt_result, 32, &ctx);
489 }
490
491 /* Add salt for numbers not divisible by 3. */
492 if (cnt % 3 != 0) {
493 sha256_process_bytes(s_bytes, salt_len, &ctx);
494 }
495
496 /* Add key for numbers not divisible by 7. */
497 if (cnt % 7 != 0) {
498 sha256_process_bytes(p_bytes, key_len, &ctx);
499 }
500
501 /* Add key or last result. */
502 if ((cnt & 1) != 0) {
503 sha256_process_bytes(alt_result, 32, &ctx);
504 } else {
505 sha256_process_bytes(p_bytes, key_len, &ctx);
506 }
507
508 /* Create intermediate result. */
509 sha256_finish_ctx(&ctx, alt_result);
510 }
511
512 /* Now we can construct the result string. It consists of three
513 parts. */
514 cp = __php_stpncpy(buffer, sha256_salt_prefix, MAX(0, buflen));
515 buflen -= sizeof(sha256_salt_prefix) - 1;
516
517 if (rounds_custom) {
518 #ifdef PHP_WIN32
519 int n = _snprintf(cp, MAX(0, buflen), "%s" ZEND_ULONG_FMT "$", sha256_rounds_prefix, rounds);
520 #else
521 int n = snprintf(cp, MAX(0, buflen), "%s%zu$", sha256_rounds_prefix, rounds);
522 #endif
523 cp += n;
524 buflen -= n;
525 }
526
527 cp = __php_stpncpy(cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
528 buflen -= MIN(MAX (0, buflen), (int)salt_len);
529
530 if (buflen > 0) {
531 *cp++ = '$';
532 --buflen;
533 }
534
535 #define b64_from_24bit(B2, B1, B0, N) \
536 do { \
537 unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
538 int n = (N); \
539 while (n-- > 0 && buflen > 0) \
540 { \
541 *cp++ = b64t[w & 0x3f]; \
542 --buflen; \
543 w >>= 6; \
544 } \
545 } while (0)
546
547 b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4);
548 b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4);
549 b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4);
550 b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4);
551 b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4);
552 b64_from_24bit(alt_result[15], alt_result[25], alt_result[5], 4);
553 b64_from_24bit(alt_result[6], alt_result[16], alt_result[26], 4);
554 b64_from_24bit(alt_result[27], alt_result[7], alt_result[17], 4);
555 b64_from_24bit(alt_result[18], alt_result[28], alt_result[8], 4);
556 b64_from_24bit(alt_result[9], alt_result[19], alt_result[29], 4);
557 b64_from_24bit(0, alt_result[31], alt_result[30], 3);
558 if (buflen <= 0) {
559 errno = ERANGE;
560 buffer = NULL;
561 } else
562 *cp = '\0'; /* Terminate the string. */
563
564 /* Clear the buffer for the intermediate result so that people
565 attaching to processes or reading core dumps cannot get any
566 information. We do it in this way to clear correct_words[]
567 inside the SHA256 implementation as well. */
568 sha256_init_ctx(&ctx);
569 sha256_finish_ctx(&ctx, alt_result);
570 ZEND_SECURE_ZERO(temp_result, sizeof(temp_result));
571 ZEND_SECURE_ZERO(p_bytes, key_len);
572 ZEND_SECURE_ZERO(s_bytes, salt_len);
573 ZEND_SECURE_ZERO(&ctx, sizeof(ctx));
574 ZEND_SECURE_ZERO(&alt_ctx, sizeof(alt_ctx));
575
576 if (copied_key != NULL) {
577 ZEND_SECURE_ZERO(copied_key, key_len);
578 }
579 if (copied_salt != NULL) {
580 ZEND_SECURE_ZERO(copied_salt, salt_len);
581 }
582 if (tmp_key != NULL) {
583 free_alloca(tmp_key, use_heap_key);
584 }
585 if (tmp_salt != NULL) {
586 free_alloca(tmp_salt, use_heap_salt);
587 }
588 free_alloca(p_bytes, use_heap_p_bytes);
589 free_alloca(s_bytes, use_heap_s_bytes);
590
591 return buffer;
592 }
593
594
595 /* This entry point is equivalent to the `crypt' function in Unix
596 libcs. */
php_sha256_crypt(const char * key,const char * salt)597 char * php_sha256_crypt(const char *key, const char *salt)
598 {
599 /* We don't want to have an arbitrary limit in the size of the
600 password. We can compute an upper bound for the size of the
601 result in advance and so we can prepare the buffer we pass to
602 `sha256_crypt_r'. */
603 ZEND_TLS char *buffer;
604 ZEND_TLS int buflen = 0;
605 int needed = (sizeof(sha256_salt_prefix) - 1
606 + sizeof(sha256_rounds_prefix) + 9 + 1
607 + (int)strlen(salt) + 1 + 43 + 1);
608
609 if (buflen < needed) {
610 char *new_buffer = (char *) realloc(buffer, needed);
611 if (new_buffer == NULL) {
612 return NULL;
613 }
614
615 buffer = new_buffer;
616 buflen = needed;
617 }
618
619 return php_sha256_crypt_r(key, salt, buffer, buflen);
620 }
621
622
623 #ifdef TEST
624 static const struct
625 {
626 const char *input;
627 const char result[32];
628 } tests[] =
629 {
630 /* Test vectors from FIPS 180-2: appendix B.1. */
631 { "abc",
632 "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
633 "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
634 /* Test vectors from FIPS 180-2: appendix B.2. */
635 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
636 "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
637 "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
638 /* Test vectors from the NESSIE project. */
639 { "",
640 "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24"
641 "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55" },
642 { "a",
643 "\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d"
644 "\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb" },
645 { "message digest",
646 "\xf7\x84\x6f\x55\xcf\x23\xe1\x4e\xeb\xea\xb5\xb4\xe1\x55\x0c\xad"
647 "\x5b\x50\x9e\x33\x48\xfb\xc4\xef\xa3\xa1\x41\x3d\x39\x3c\xb6\x50" },
648 { "abcdefghijklmnopqrstuvwxyz",
649 "\x71\xc4\x80\xdf\x93\xd6\xae\x2f\x1e\xfa\xd1\x44\x7c\x66\xc9\x52"
650 "\x5e\x31\x62\x18\xcf\x51\xfc\x8d\x9e\xd8\x32\xf2\xda\xf1\x8b\x73" },
651 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
652 "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
653 "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
654 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
655 "\xdb\x4b\xfc\xbd\x4d\xa0\xcd\x85\xa6\x0c\x3c\x37\xd3\xfb\xd8\x80"
656 "\x5c\x77\xf1\x5f\xc6\xb1\xfd\xfe\x61\x4e\xe0\xa7\xc8\xfd\xb4\xc0" },
657 { "123456789012345678901234567890123456789012345678901234567890"
658 "12345678901234567890",
659 "\xf3\x71\xbc\x4a\x31\x1f\x2b\x00\x9e\xef\x95\x2d\xd8\x3c\xa8\x0e"
660 "\x2b\x60\x02\x6c\x8e\x93\x55\x92\xd0\xf9\xc3\x08\x45\x3c\x81\x3e" }
661 };
662 #define ntests (sizeof (tests) / sizeof (tests[0]))
663
664
665 static const struct
666 {
667 const char *salt;
668 const char *input;
669 const char *expected;
670 } tests2[] =
671 {
672 { "$5$saltstring", "Hello world!",
673 "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5" },
674 { "$5$rounds=10000$saltstringsaltstring", "Hello world!",
675 "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2."
676 "opqey6IcA" },
677 { "$5$rounds=5000$toolongsaltstring", "This is just a test",
678 "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8"
679 "mGRcvxa5" },
680 { "$5$rounds=1400$anotherlongsaltstring",
681 "a very much longer text to encrypt. This one even stretches over more"
682 "than one line.",
683 "$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12"
684 "oP84Bnq1" },
685 { "$5$rounds=77777$short",
686 "we have a short salt string but not a short password",
687 "$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/" },
688 { "$5$rounds=123456$asaltof16chars..", "a short string",
689 "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/"
690 "cZKmF/wJvD" },
691 { "$5$rounds=10$roundstoolow", "the minimum number is still observed",
692 "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97"
693 "2bIC" },
694 };
695 #define ntests2 (sizeof (tests2) / sizeof (tests2[0]))
696
697
main(void)698 int main(void) {
699 struct sha256_ctx ctx;
700 char sum[32];
701 int result = 0;
702 int cnt, i;
703 char buf[1000];
704 static const char expected[32] =
705 "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
706 "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0";
707
708 for (cnt = 0; cnt < (int) ntests; ++cnt) {
709 sha256_init_ctx(&ctx);
710 sha256_process_bytes(tests[cnt].input, strlen(tests[cnt].input), &ctx);
711 sha256_finish_ctx(&ctx, sum);
712 if (memcmp(tests[cnt].result, sum, 32) != 0) {
713 printf("test %d run %d failed\n", cnt, 1);
714 result = 1;
715 }
716
717 sha256_init_ctx(&ctx);
718 for (i = 0; tests[cnt].input[i] != '\0'; ++i) {
719 sha256_process_bytes(&tests[cnt].input[i], 1, &ctx);
720 }
721 sha256_finish_ctx(&ctx, sum);
722 if (memcmp(tests[cnt].result, sum, 32) != 0) {
723 printf("test %d run %d failed\n", cnt, 2);
724 result = 1;
725 }
726 }
727
728 /* Test vector from FIPS 180-2: appendix B.3. */
729
730 memset(buf, 'a', sizeof(buf));
731 sha256_init_ctx(&ctx);
732 for (i = 0; i < 1000; ++i) {
733 sha256_process_bytes (buf, sizeof (buf), &ctx);
734 }
735
736 sha256_finish_ctx(&ctx, sum);
737
738 if (memcmp(expected, sum, 32) != 0) {
739 printf("test %d failed\n", cnt);
740 result = 1;
741 }
742
743 for (cnt = 0; cnt < ntests2; ++cnt) {
744 char *cp = php_sha256_crypt(tests2[cnt].input, tests2[cnt].salt);
745 if (strcmp(cp, tests2[cnt].expected) != 0) {
746 printf("test %d: expected \"%s\", got \"%s\"\n", cnt, tests2[cnt].expected, cp);
747 result = 1;
748 }
749 }
750
751 if (result == 0)
752 puts("all tests OK");
753
754 return result;
755 }
756 #endif
757