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