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