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