xref: /php-src/ext/hash/hash_sha.c (revision 6eca7839)
1 /*
2   +----------------------------------------------------------------------+
3   | Copyright (c) The PHP Group                                          |
4   +----------------------------------------------------------------------+
5   | This source file is subject to version 3.01 of the PHP license,      |
6   | that is bundled with this package in the file LICENSE, and is        |
7   | available through the world-wide-web at the following url:           |
8   | https://www.php.net/license/3_01.txt                                 |
9   | If you did not receive a copy of the PHP license and are unable to   |
10   | obtain it through the world-wide-web, please send a note to          |
11   | license@php.net so we can mail you a copy immediately.               |
12   +----------------------------------------------------------------------+
13   | Authors: Steffan Esser <sesser@php.net>                              |
14   |          Sara Golemon <pollita@php.net>                              |
15   +----------------------------------------------------------------------+
16 */
17 
18 #include "php_hash.h"
19 #include "php_hash_sha.h"
20 #include "Zend/zend_cpuinfo.h"
21 
22 static const unsigned char PADDING[128] =
23 {
24 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
32 };
33 
34 /* {{{ SHAEncode32
35    Encodes input (uint32_t) into output (unsigned char). Assumes len is
36    a multiple of 4.
37  */
SHAEncode32(unsigned char * output,uint32_t * input,unsigned int len)38 static void SHAEncode32(unsigned char *output, uint32_t *input, unsigned int len)
39 {
40 	unsigned int i, j;
41 
42 	for (i = 0, j = 0; j < len; i++, j += 4) {
43 		output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
44 		output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
45 		output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
46 		output[j + 3] = (unsigned char) (input[i] & 0xff);
47 	}
48 }
49 /* }}} */
50 
51 
52 /* {{{ SHADecode32
53    Decodes input (unsigned char) into output (uint32_t). Assumes len is
54    a multiple of 4.
55  */
SHADecode32(uint32_t * output,const unsigned char * input,unsigned int len)56 static void SHADecode32(uint32_t *output, const unsigned char *input, unsigned int len)
57 {
58 	unsigned int i, j;
59 
60 	for (i = 0, j = 0; j < len; i++, j += 4)
61 		output[i] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) |
62 			(((uint32_t) input[j + 1]) << 16) | (((uint32_t) input[j]) << 24);
63 }
64 /* }}} */
65 
66 const php_hash_ops php_hash_sha1_ops = {
67 	"sha1",
68 	(php_hash_init_func_t) PHP_SHA1InitArgs,
69 	(php_hash_update_func_t) PHP_SHA1Update,
70 	(php_hash_final_func_t) PHP_SHA1Final,
71 	php_hash_copy,
72 	php_hash_serialize,
73 	php_hash_unserialize,
74 	PHP_SHA1_SPEC,
75 	20,
76 	64,
77 	sizeof(PHP_SHA1_CTX),
78 	1
79 };
80 
81 /* sha224/sha256 */
82 
83 const php_hash_ops php_hash_sha256_ops = {
84 	"sha256",
85 	(php_hash_init_func_t) PHP_SHA256InitArgs,
86 	(php_hash_update_func_t) PHP_SHA256Update,
87 	(php_hash_final_func_t) PHP_SHA256Final,
88 	php_hash_copy,
89 	php_hash_serialize,
90 	php_hash_unserialize,
91 	PHP_SHA256_SPEC,
92 	32,
93 	64,
94 	sizeof(PHP_SHA256_CTX),
95 	1
96 };
97 
98 const php_hash_ops php_hash_sha224_ops = {
99 	"sha224",
100 	(php_hash_init_func_t) PHP_SHA224InitArgs,
101 	(php_hash_update_func_t) PHP_SHA224Update,
102 	(php_hash_final_func_t) PHP_SHA224Final,
103 	php_hash_copy,
104 	php_hash_serialize,
105 	php_hash_unserialize,
106 	PHP_SHA224_SPEC,
107 	28,
108 	64,
109 	sizeof(PHP_SHA224_CTX),
110 	1
111 };
112 
113 #define ROTR32(b,x)		((x >> b) | (x << (32 - b)))
114 #define ROTR64(b,x)		((x >> b) | (x << (64 - b)))
115 #define SHR(b, x)		(x >> b)
116 
117 /* Ch */
118 #define SHA256_F0(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
119 /* Maj */
120 #define SHA256_F1(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
121 /* SUM0 */
122 #define SHA256_F2(x)		(ROTR32( 2,(x)) ^ ROTR32(13,(x)) ^ ROTR32(22,(x)))
123 /* SUM1 */
124 #define SHA256_F3(x)		(ROTR32( 6,(x)) ^ ROTR32(11,(x)) ^ ROTR32(25,(x)))
125 /* OM0 */
126 #define SHA256_F4(x)		(ROTR32( 7,(x)) ^ ROTR32(18,(x)) ^ SHR( 3,(x)))
127 /* OM1 */
128 #define SHA256_F5(x)		(ROTR32(17,(x)) ^ ROTR32(19,(x)) ^ SHR(10,(x)))
129 
130 static const uint32_t SHA256_K[64] = {
131 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
132 	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
133 	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
134 	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
135 	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
136 	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
137 	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
138 	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
139 
140 /* {{{ PHP_SHA256InitArgs
141  * SHA256 initialization. Begins an SHA256 operation, writing a new context.
142  */
PHP_SHA256InitArgs(PHP_SHA256_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)143 PHP_HASH_API void PHP_SHA256InitArgs(PHP_SHA256_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
144 {
145 	context->count[0] = context->count[1] = 0;
146 	/* Load magic initialization constants.
147 	 */
148 	context->state[0] = 0x6a09e667;
149 	context->state[1] = 0xbb67ae85;
150 	context->state[2] = 0x3c6ef372;
151 	context->state[3] = 0xa54ff53a;
152 	context->state[4] = 0x510e527f;
153 	context->state[5] = 0x9b05688c;
154 	context->state[6] = 0x1f83d9ab;
155 	context->state[7] = 0x5be0cd19;
156 }
157 /* }}} */
158 
159 /* {{{ SHA256Transform
160  * SHA256 basic transformation. Transforms state based on block.
161  */
SHA256Transform(uint32_t state[8],const unsigned char block[64])162 static void SHA256Transform(uint32_t state[8], const unsigned char block[64])
163 {
164 #if defined(PHP_HASH_INTRIN_SHA_NATIVE)
165 	SHA256_Transform_shani(state, block);
166 	return;
167 #elif defined(PHP_HASH_INTRIN_SHA_RESOLVER)
168 	if (zend_cpu_supports(ZEND_CPU_FEATURE_SSSE3) && zend_cpu_supports(ZEND_CPU_FEATURE_SHA)) {
169 		SHA256_Transform_shani(state, block);
170 		return;
171 	}
172 #endif
173 
174 #if defined(__SSE2__)
175 	uint32_t tmp32[72];
176 
177 	SHA256_Transform_sse2(state, block, &tmp32[0], &tmp32[64]);
178 	ZEND_SECURE_ZERO((unsigned char*) tmp32, sizeof(tmp32));
179 	return;
180 #endif
181 
182 	uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
183 	uint32_t e = state[4], f = state[5], g = state[6], h = state[7];
184 	uint32_t x[16], T1, T2, W[64];
185 	int i;
186 
187 	SHADecode32(x, block, 64);
188 
189 	/* Schedule */
190 	for(i = 0; i < 16; i++) {
191 		W[i] = x[i];
192 	}
193 	for(i = 16; i < 64; i++) {
194 		W[i] = SHA256_F5(W[i-2]) + W[i-7] + SHA256_F4(W[i-15]) + W[i-16];
195 	}
196 
197 	for (i = 0; i < 64; i++) {
198 		T1 = h + SHA256_F3(e) + SHA256_F0(e,f,g) + SHA256_K[i] + W[i];
199 		T2 = SHA256_F2(a) + SHA256_F1(a,b,c);
200 		h = g; g = f; f = e; e = d + T1;
201 		d = c; c = b; b = a; a = T1 + T2;
202 	}
203 
204 	state[0] += a;
205 	state[1] += b;
206 	state[2] += c;
207 	state[3] += d;
208 	state[4] += e;
209 	state[5] += f;
210 	state[6] += g;
211 	state[7] += h;
212 
213 	/* Zeroize sensitive information. */
214 	ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
215 }
216 /* }}} */
217 
218 /* {{{ PHP_SHA224InitArgs
219  * SHA224 initialization. Begins an SHA224 operation, writing a new context.
220  */
PHP_SHA224InitArgs(PHP_SHA224_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)221 PHP_HASH_API void PHP_SHA224InitArgs(PHP_SHA224_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
222 {
223 	context->count[0] = context->count[1] = 0;
224 	/* Load magic initialization constants.
225 	 */
226 	context->state[0] = 0xc1059ed8;
227 	context->state[1] = 0x367cd507;
228 	context->state[2] = 0x3070dd17;
229 	context->state[3] = 0xf70e5939;
230 	context->state[4] = 0xffc00b31;
231 	context->state[5] = 0x68581511;
232 	context->state[6] = 0x64f98fa7;
233 	context->state[7] = 0xbefa4fa4;
234 }
235 /* }}} */
236 
237 /* {{{ PHP_SHA224Update
238    SHA224 block update operation. Continues an SHA224 message-digest
239    operation, processing another message block, and updating the
240    context.
241  */
PHP_SHA224Update(PHP_SHA224_CTX * context,const unsigned char * input,size_t inputLen)242 PHP_HASH_API void PHP_SHA224Update(PHP_SHA224_CTX * context, const unsigned char *input, size_t inputLen)
243 {
244 	unsigned int index, partLen;
245 	size_t i;
246 
247 	/* Compute number of bytes mod 64 */
248 	index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
249 
250 	/* Update number of bits */
251 	if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
252 		context->count[1]++;
253 	}
254 	context->count[1] += (uint32_t) (inputLen >> 29);
255 
256 	partLen = 64 - index;
257 
258 	/* Transform as many times as possible.
259 	 */
260 	if (inputLen >= partLen) {
261 		memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
262 		SHA256Transform(context->state, context->buffer);
263 
264 		for (i = partLen; i + 63 < inputLen; i += 64) {
265 			SHA256Transform(context->state, &input[i]);
266 		}
267 
268 		index = 0;
269 	} else {
270 		i = 0;
271 	}
272 
273 	/* Buffer remaining input */
274 	memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
275 }
276 /* }}} */
277 
278 /* {{{ PHP_SHA224Final
279    SHA224 finalization. Ends an SHA224 message-digest operation, writing the
280    the message digest and zeroizing the context.
281  */
PHP_SHA224Final(unsigned char digest[28],PHP_SHA224_CTX * context)282 PHP_HASH_API void PHP_SHA224Final(unsigned char digest[28], PHP_SHA224_CTX * context)
283 {
284 	unsigned char bits[8];
285 	unsigned int index, padLen;
286 
287 	/* Save number of bits */
288 	bits[7] = (unsigned char) (context->count[0] & 0xFF);
289 	bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
290 	bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
291 	bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
292 	bits[3] = (unsigned char) (context->count[1] & 0xFF);
293 	bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
294 	bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
295 	bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
296 
297 	/* Pad out to 56 mod 64.
298 	 */
299 	index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
300 	padLen = (index < 56) ? (56 - index) : (120 - index);
301 	PHP_SHA224Update(context, PADDING, padLen);
302 
303 	/* Append length (before padding) */
304 	PHP_SHA224Update(context, bits, 8);
305 
306 	/* Store state in digest */
307 	SHAEncode32(digest, context->state, 28);
308 
309 	/* Zeroize sensitive information.
310 	 */
311 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
312 }
313 /* }}} */
314 
315 /* {{{ PHP_SHA256Update
316    SHA256 block update operation. Continues an SHA256 message-digest
317    operation, processing another message block, and updating the
318    context.
319  */
PHP_SHA256Update(PHP_SHA256_CTX * context,const unsigned char * input,size_t inputLen)320 PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, size_t inputLen)
321 {
322 	unsigned int index, partLen;
323 	size_t i;
324 
325 	/* Compute number of bytes mod 64 */
326 	index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
327 
328 	/* Update number of bits */
329 	if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
330 		context->count[1]++;
331 	}
332 	context->count[1] += (uint32_t) (inputLen >> 29);
333 
334 	partLen = 64 - index;
335 
336 	/* Transform as many times as possible.
337 	 */
338 	if (inputLen >= partLen) {
339 		memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
340 		SHA256Transform(context->state, context->buffer);
341 
342 		for (i = partLen; i + 63 < inputLen; i += 64) {
343 			SHA256Transform(context->state, &input[i]);
344 		}
345 
346 		index = 0;
347 	} else {
348 		i = 0;
349 	}
350 
351 	/* Buffer remaining input */
352 	memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
353 }
354 /* }}} */
355 
356 /* {{{ PHP_SHA256Final
357    SHA256 finalization. Ends an SHA256 message-digest operation, writing the
358    the message digest and zeroizing the context.
359  */
PHP_SHA256Final(unsigned char digest[32],PHP_SHA256_CTX * context)360 PHP_HASH_API void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
361 {
362 	unsigned char bits[8];
363 	unsigned int index, padLen;
364 
365 	/* Save number of bits */
366 	bits[7] = (unsigned char) (context->count[0] & 0xFF);
367 	bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
368 	bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
369 	bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
370 	bits[3] = (unsigned char) (context->count[1] & 0xFF);
371 	bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
372 	bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
373 	bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
374 
375 	/* Pad out to 56 mod 64.
376 	 */
377 	index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
378 	padLen = (index < 56) ? (56 - index) : (120 - index);
379 	PHP_SHA256Update(context, PADDING, padLen);
380 
381 	/* Append length (before padding) */
382 	PHP_SHA256Update(context, bits, 8);
383 
384 	/* Store state in digest */
385 	SHAEncode32(digest, context->state, 32);
386 
387 	/* Zeroize sensitive information.
388 	 */
389 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
390 }
391 /* }}} */
392 
393 /* sha384/sha512 */
394 
395 /* Ch */
396 #define SHA512_F0(x,y,z)		(((x) & (y)) ^ ((~(x)) & (z)))
397 /* Maj */
398 #define SHA512_F1(x,y,z)		(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
399 /* SUM0 */
400 #define SHA512_F2(x)			(ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x))
401 /* SUM1 */
402 #define SHA512_F3(x)			(ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x))
403 /* OM0 */
404 #define SHA512_F4(x)			(ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR(7, x))
405 /* OM1 */
406 #define SHA512_F5(x)			(ROTR64(19, x) ^ ROTR64(61, x) ^ SHR(6, x))
407 
408 static const uint64_t SHA512_K[128] = {
409 	L64(0x428a2f98d728ae22), L64(0x7137449123ef65cd), L64(0xb5c0fbcfec4d3b2f), L64(0xe9b5dba58189dbbc),
410 	L64(0x3956c25bf348b538), L64(0x59f111f1b605d019), L64(0x923f82a4af194f9b), L64(0xab1c5ed5da6d8118),
411 	L64(0xd807aa98a3030242), L64(0x12835b0145706fbe), L64(0x243185be4ee4b28c), L64(0x550c7dc3d5ffb4e2),
412 	L64(0x72be5d74f27b896f), L64(0x80deb1fe3b1696b1), L64(0x9bdc06a725c71235), L64(0xc19bf174cf692694),
413 	L64(0xe49b69c19ef14ad2), L64(0xefbe4786384f25e3), L64(0x0fc19dc68b8cd5b5), L64(0x240ca1cc77ac9c65),
414 	L64(0x2de92c6f592b0275), L64(0x4a7484aa6ea6e483), L64(0x5cb0a9dcbd41fbd4), L64(0x76f988da831153b5),
415 	L64(0x983e5152ee66dfab), L64(0xa831c66d2db43210), L64(0xb00327c898fb213f), L64(0xbf597fc7beef0ee4),
416 	L64(0xc6e00bf33da88fc2), L64(0xd5a79147930aa725), L64(0x06ca6351e003826f), L64(0x142929670a0e6e70),
417 	L64(0x27b70a8546d22ffc), L64(0x2e1b21385c26c926), L64(0x4d2c6dfc5ac42aed), L64(0x53380d139d95b3df),
418 	L64(0x650a73548baf63de), L64(0x766a0abb3c77b2a8), L64(0x81c2c92e47edaee6), L64(0x92722c851482353b),
419 	L64(0xa2bfe8a14cf10364), L64(0xa81a664bbc423001), L64(0xc24b8b70d0f89791), L64(0xc76c51a30654be30),
420 	L64(0xd192e819d6ef5218), L64(0xd69906245565a910), L64(0xf40e35855771202a), L64(0x106aa07032bbd1b8),
421 	L64(0x19a4c116b8d2d0c8), L64(0x1e376c085141ab53), L64(0x2748774cdf8eeb99), L64(0x34b0bcb5e19b48a8),
422 	L64(0x391c0cb3c5c95a63), L64(0x4ed8aa4ae3418acb), L64(0x5b9cca4f7763e373), L64(0x682e6ff3d6b2b8a3),
423 	L64(0x748f82ee5defb2fc), L64(0x78a5636f43172f60), L64(0x84c87814a1f0ab72), L64(0x8cc702081a6439ec),
424 	L64(0x90befffa23631e28), L64(0xa4506cebde82bde9), L64(0xbef9a3f7b2c67915), L64(0xc67178f2e372532b),
425 	L64(0xca273eceea26619c), L64(0xd186b8c721c0c207), L64(0xeada7dd6cde0eb1e), L64(0xf57d4f7fee6ed178),
426 	L64(0x06f067aa72176fba), L64(0x0a637dc5a2c898a6), L64(0x113f9804bef90dae), L64(0x1b710b35131c471b),
427 	L64(0x28db77f523047d84), L64(0x32caab7b40c72493), L64(0x3c9ebe0a15c9bebc), L64(0x431d67c49c100d4c),
428 	L64(0x4cc5d4becb3e42b6), L64(0x597f299cfc657e2a), L64(0x5fcb6fab3ad6faec), L64(0x6c44198c4a475817) };
429 
430 /* {{{ SHAEncode64
431    Encodes input (uint64_t) into output (unsigned char). Assumes len is
432    a multiple of 8.
433  */
SHAEncode64(unsigned char * output,uint64_t * input,unsigned int len)434 static void SHAEncode64(unsigned char *output, uint64_t *input, unsigned int len)
435 {
436 	unsigned int i, j;
437 
438 	for (i = 0, j = 0; j < len; i++, j += 8) {
439 		output[j] = (unsigned char) ((input[i] >> 56) & 0xff);
440 		output[j + 1] = (unsigned char) ((input[i] >> 48) & 0xff);
441 		output[j + 2] = (unsigned char) ((input[i] >> 40) & 0xff);
442 		output[j + 3] = (unsigned char) ((input[i] >> 32) & 0xff);
443 		output[j + 4] = (unsigned char) ((input[i] >> 24) & 0xff);
444 		output[j + 5] = (unsigned char) ((input[i] >> 16) & 0xff);
445 		output[j + 6] = (unsigned char) ((input[i] >> 8) & 0xff);
446 		output[j + 7] = (unsigned char) (input[i] & 0xff);
447 	}
448 }
449 /* }}} */
450 
451 
452 /* {{{ SHADecode64
453    Decodes input (unsigned char) into output (uint64_t). Assumes len is
454    a multiple of 8.
455  */
SHADecode64(uint64_t * output,const unsigned char * input,unsigned int len)456 static void SHADecode64(uint64_t *output, const unsigned char *input, unsigned int len)
457 {
458 	unsigned int i, j;
459 
460 	for (i = 0, j = 0; j < len; i++, j += 8)
461 		output[i] =
462 			((uint64_t) input[j + 7]) | (((uint64_t) input[j + 6]) << 8) |
463 			(((uint64_t) input[j + 5]) << 16) | (((uint64_t) input[j + 4]) << 24) |
464 			(((uint64_t) input[j + 3]) << 32) | (((uint64_t) input[j + 2]) << 40) |
465 			(((uint64_t) input[j + 1]) << 48) | (((uint64_t) input[j]) << 56);
466 }
467 /* }}} */
468 
469 /* {{{ PHP_SHA384InitArgs
470  * SHA384 initialization. Begins an SHA384 operation, writing a new context.
471  */
PHP_SHA384InitArgs(PHP_SHA384_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)472 PHP_HASH_API void PHP_SHA384InitArgs(PHP_SHA384_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
473 {
474 	context->count[0] = context->count[1] = 0;
475 	/* Load magic initialization constants.
476 	 */
477 	context->state[0] = L64(0xcbbb9d5dc1059ed8);
478 	context->state[1] = L64(0x629a292a367cd507);
479 	context->state[2] = L64(0x9159015a3070dd17);
480 	context->state[3] = L64(0x152fecd8f70e5939);
481 	context->state[4] = L64(0x67332667ffc00b31);
482 	context->state[5] = L64(0x8eb44a8768581511);
483 	context->state[6] = L64(0xdb0c2e0d64f98fa7);
484 	context->state[7] = L64(0x47b5481dbefa4fa4);
485 }
486 /* }}} */
487 
488 /* {{{ SHA512Transform
489  * SHA512 basic transformation. Transforms state based on block.
490  * SHA384 uses the exact same algorithm
491  */
SHA512Transform(uint64_t state[8],const unsigned char block[128])492 static void SHA512Transform(uint64_t state[8], const unsigned char block[128])
493 {
494 	uint64_t a = state[0], b = state[1], c = state[2], d = state[3];
495 	uint64_t e = state[4], f = state[5], g = state[6], h = state[7];
496 	uint64_t x[16], T1, T2, W[80];
497 	int i;
498 
499 	SHADecode64(x, block, 128);
500 
501 	/* Schedule */
502 	for(i = 0; i < 16; i++) {
503 		W[i] = x[i];
504 	}
505 	for(i = 16; i < 80; i++) {
506 		W[i] = SHA512_F5(W[i-2]) + W[i-7] + SHA512_F4(W[i-15]) + W[i-16];
507 	}
508 
509 	for (i = 0; i < 80; i++) {
510 		T1 = h + SHA512_F3(e) + SHA512_F0(e,f,g) + SHA512_K[i] + W[i];
511 		T2 = SHA512_F2(a) + SHA512_F1(a,b,c);
512 		h = g; g = f; f = e; e = d + T1;
513 		d = c; c = b; b = a; a = T1 + T2;
514 	}
515 
516 	state[0] += a;
517 	state[1] += b;
518 	state[2] += c;
519 	state[3] += d;
520 	state[4] += e;
521 	state[5] += f;
522 	state[6] += g;
523 	state[7] += h;
524 
525 	/* Zeroize sensitive information. */
526 	ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
527 }
528 /* }}} */
529 
530 /* {{{ PHP_SHA384Update
531    SHA384 block update operation. Continues an SHA384 message-digest
532    operation, processing another message block, and updating the
533    context.
534  */
PHP_SHA384Update(PHP_SHA384_CTX * context,const unsigned char * input,size_t inputLen)535 PHP_HASH_API void PHP_SHA384Update(PHP_SHA384_CTX * context, const unsigned char *input, size_t inputLen)
536 {
537 	unsigned int index, partLen;
538 	size_t i = 0;
539 
540 	/* Compute number of bytes mod 128 */
541 	index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
542 
543 	/* Update number of bits */
544 	if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
545 		context->count[1]++;
546 	}
547 	/* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
548 	context->count[1] += (uint64_t) inputLen >> 61;
549 
550 	partLen = 128 - index;
551 
552 	/* Transform as many times as possible.
553 	 */
554 	if (inputLen >= partLen) {
555 		memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
556 		SHA512Transform(context->state, context->buffer);
557 
558 		for (i = partLen; i + 127 < inputLen; i += 128) {
559 			SHA512Transform(context->state, &input[i]);
560 		}
561 
562 		index = 0;
563 	}
564 
565 	/* Buffer remaining input */
566 	memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
567 }
568 /* }}} */
569 
570 /* {{{ PHP_SHA384Final
571    SHA384 finalization. Ends an SHA384 message-digest operation, writing the
572    the message digest and zeroizing the context.
573  */
PHP_SHA384Final(unsigned char digest[48],PHP_SHA384_CTX * context)574 PHP_HASH_API void PHP_SHA384Final(unsigned char digest[48], PHP_SHA384_CTX * context)
575 {
576 	unsigned char bits[16];
577 	unsigned int index, padLen;
578 
579 	/* Save number of bits */
580 	bits[15] = (unsigned char) (context->count[0] & 0xFF);
581 	bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
582 	bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
583 	bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
584 	bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
585 	bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
586 	bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
587 	bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
588 	bits[7]  = (unsigned char) (context->count[1] & 0xFF);
589 	bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
590 	bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
591 	bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
592 	bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
593 	bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
594 	bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
595 	bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
596 
597 	/* Pad out to 112 mod 128.
598 	 */
599 	index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
600 	padLen = (index < 112) ? (112 - index) : (240 - index);
601 	PHP_SHA384Update(context, PADDING, padLen);
602 
603 	/* Append length (before padding) */
604 	PHP_SHA384Update(context, bits, 16);
605 
606 	/* Store state in digest */
607 	SHAEncode64(digest, context->state, 48);
608 
609 	/* Zeroize sensitive information.
610 	 */
611 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
612 }
613 /* }}} */
614 
615 const php_hash_ops php_hash_sha384_ops = {
616 	"sha384",
617 	(php_hash_init_func_t) PHP_SHA384InitArgs,
618 	(php_hash_update_func_t) PHP_SHA384Update,
619 	(php_hash_final_func_t) PHP_SHA384Final,
620 	php_hash_copy,
621 	php_hash_serialize,
622 	php_hash_unserialize,
623 	PHP_SHA384_SPEC,
624 	48,
625 	128,
626 	sizeof(PHP_SHA384_CTX),
627 	1
628 };
629 
630 /* {{{ PHP_SHA512InitArgs
631  * SHA512 initialization. Begins an SHA512 operation, writing a new context.
632  */
PHP_SHA512InitArgs(PHP_SHA512_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)633 PHP_HASH_API void PHP_SHA512InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
634 {
635 	context->count[0] = context->count[1] = 0;
636 	/* Load magic initialization constants.
637 	 */
638 	context->state[0] = L64(0x6a09e667f3bcc908);
639 	context->state[1] = L64(0xbb67ae8584caa73b);
640 	context->state[2] = L64(0x3c6ef372fe94f82b);
641 	context->state[3] = L64(0xa54ff53a5f1d36f1);
642 	context->state[4] = L64(0x510e527fade682d1);
643 	context->state[5] = L64(0x9b05688c2b3e6c1f);
644 	context->state[6] = L64(0x1f83d9abfb41bd6b);
645 	context->state[7] = L64(0x5be0cd19137e2179);
646 }
647 /* }}} */
648 
649 /* {{{ PHP_SHA512_256InitArgs
650  * SHA512/245 initialization. Identical algorithm to SHA512, using alternate initval and truncation
651  */
PHP_SHA512_256InitArgs(PHP_SHA512_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)652 PHP_HASH_API void PHP_SHA512_256InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
653 {
654 	context->count[0] = context->count[1] = 0;
655 
656 	context->state[0] = L64(0x22312194FC2BF72C);
657 	context->state[1] = L64(0x9F555FA3C84C64C2);
658 	context->state[2] = L64(0x2393B86B6F53B151);
659 	context->state[3] = L64(0x963877195940EABD);
660 	context->state[4] = L64(0x96283EE2A88EFFE3);
661 	context->state[5] = L64(0xBE5E1E2553863992);
662 	context->state[6] = L64(0x2B0199FC2C85B8AA);
663 	context->state[7] = L64(0x0EB72DDC81C52CA2);
664 }
665 /* }}} */
666 
667 /* {{{ PHP_SHA512_224InitArgs
668  * SHA512/224 initialization. Identical algorithm to SHA512, using alternate initval and truncation
669  */
PHP_SHA512_224InitArgs(PHP_SHA512_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)670 PHP_HASH_API void PHP_SHA512_224InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
671 {
672         context->count[0] = context->count[1] = 0;
673 
674 	context->state[0] = L64(0x8C3D37C819544DA2);
675 	context->state[1] = L64(0x73E1996689DCD4D6);
676 	context->state[2] = L64(0x1DFAB7AE32FF9C82);
677 	context->state[3] = L64(0x679DD514582F9FCF);
678 	context->state[4] = L64(0x0F6D2B697BD44DA8);
679 	context->state[5] = L64(0x77E36F7304C48942);
680 	context->state[6] = L64(0x3F9D85A86A1D36C8);
681 	context->state[7] = L64(0x1112E6AD91D692A1);
682 }
683 /* }}} */
684 
685 /* {{{ PHP_SHA512Update
686    SHA512 block update operation. Continues an SHA512 message-digest
687    operation, processing another message block, and updating the
688    context.
689  */
PHP_SHA512Update(PHP_SHA512_CTX * context,const unsigned char * input,size_t inputLen)690 PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX * context, const unsigned char *input, size_t inputLen)
691 {
692 	unsigned int index, partLen;
693 	size_t i;
694 
695 	/* Compute number of bytes mod 128 */
696 	index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
697 
698 	/* Update number of bits */
699 	if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
700 		context->count[1]++;
701 	}
702 	/* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
703 	context->count[1] += (uint64_t) inputLen >> 61;
704 
705 	partLen = 128 - index;
706 
707 	/* Transform as many times as possible.
708 	 */
709 	if (inputLen >= partLen) {
710 		memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
711 		SHA512Transform(context->state, context->buffer);
712 
713 		for (i = partLen; i + 127 < inputLen; i += 128) {
714 			SHA512Transform(context->state, &input[i]);
715 		}
716 
717 		index = 0;
718 	} else {
719 		i = 0;
720 	}
721 
722 	/* Buffer remaining input */
723 	memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
724 }
725 /* }}} */
726 
727 /* {{{ PHP_SHA512Final
728    SHA512 finalization. Ends an SHA512 message-digest operation, writing the
729    the message digest and zeroizing the context.
730  */
PHP_SHA512Final(unsigned char digest[64],PHP_SHA512_CTX * context)731 PHP_HASH_API void PHP_SHA512Final(unsigned char digest[64], PHP_SHA512_CTX * context)
732 {
733 	unsigned char bits[16];
734 	unsigned int index, padLen;
735 
736 	/* Save number of bits */
737 	bits[15] = (unsigned char) (context->count[0] & 0xFF);
738 	bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
739 	bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
740 	bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
741 	bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
742 	bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
743 	bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
744 	bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
745 	bits[7]  = (unsigned char) (context->count[1] & 0xFF);
746 	bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
747 	bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
748 	bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
749 	bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
750 	bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
751 	bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
752 	bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
753 
754 	/* Pad out to 112 mod 128.
755 	 */
756 	index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
757 	padLen = (index < 112) ? (112 - index) : (240 - index);
758 	PHP_SHA512Update(context, PADDING, padLen);
759 
760 	/* Append length (before padding) */
761 	PHP_SHA512Update(context, bits, 16);
762 
763 	/* Store state in digest */
764 	SHAEncode64(digest, context->state, 64);
765 
766 	/* Zeroize sensitive information.
767 	 */
768 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
769 }
770 /* }}} */
771 
772 /* {{{ PHP_SHA512_256Final
773    SHA512/256 finalization. Identical to SHA512Final, but with truncation
774  */
PHP_SHA512_256Final(unsigned char digest[32],PHP_SHA512_CTX * context)775 PHP_HASH_API void PHP_SHA512_256Final(unsigned char digest[32], PHP_SHA512_CTX * context)
776 {
777 	unsigned char full_digest[64];
778 	PHP_SHA512Final(full_digest, context);
779 	memcpy(digest, full_digest, 32);
780 }
781 /* }}} */
782 
783 /* {{{ PHP_SHA512_224Final
784    SHA512/224 finalization. Identical to SHA512Final, but with truncation
785  */
PHP_SHA512_224Final(unsigned char digest[28],PHP_SHA512_CTX * context)786 PHP_HASH_API void PHP_SHA512_224Final(unsigned char digest[28], PHP_SHA512_CTX * context)
787 {
788 	unsigned char full_digest[64];
789 	PHP_SHA512Final(full_digest, context);
790 	memcpy(digest, full_digest, 28);
791 }
792 /* }}} */
793 
794 const php_hash_ops php_hash_sha512_ops = {
795 	"sha512",
796 	(php_hash_init_func_t) PHP_SHA512InitArgs,
797 	(php_hash_update_func_t) PHP_SHA512Update,
798 	(php_hash_final_func_t) PHP_SHA512Final,
799 	php_hash_copy,
800 	php_hash_serialize,
801 	php_hash_unserialize,
802 	PHP_SHA512_SPEC,
803 	64,
804 	128,
805 	sizeof(PHP_SHA512_CTX),
806 	1
807 };
808 
809 const php_hash_ops php_hash_sha512_256_ops = {
810 	"sha512/256",
811 	(php_hash_init_func_t) PHP_SHA512_256InitArgs,
812 	(php_hash_update_func_t) PHP_SHA512_256Update,
813 	(php_hash_final_func_t) PHP_SHA512_256Final,
814 	php_hash_copy,
815 	php_hash_serialize,
816 	php_hash_unserialize,
817 	PHP_SHA512_SPEC,
818 	32,
819 	128,
820 	sizeof(PHP_SHA512_CTX),
821 	1
822 };
823 
824 const php_hash_ops php_hash_sha512_224_ops = {
825 	"sha512/224",
826 	(php_hash_init_func_t) PHP_SHA512_224InitArgs,
827 	(php_hash_update_func_t) PHP_SHA512_224Update,
828 	(php_hash_final_func_t) PHP_SHA512_224Final,
829 	php_hash_copy,
830 	php_hash_serialize,
831 	php_hash_unserialize,
832 	PHP_SHA512_SPEC,
833 	28,
834 	128,
835 	sizeof(PHP_SHA512_CTX),
836 	1
837 };
838