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