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