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