xref: /php-src/ext/hash/hash_sha.c (revision 2ee4d358)
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 
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_SHA1InitArgs,
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_SHA256InitArgs,
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_SHA224InitArgs,
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_SHA256InitArgs
140  * SHA256 initialization. Begins an SHA256 operation, writing a new context.
141  */
PHP_SHA256InitArgs(PHP_SHA256_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)142 PHP_HASH_API void PHP_SHA256InitArgs(PHP_SHA256_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
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_SHA224InitArgs
200  * SHA224 initialization. Begins an SHA224 operation, writing a new context.
201  */
PHP_SHA224InitArgs(PHP_SHA224_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)202 PHP_HASH_API void PHP_SHA224InitArgs(PHP_SHA224_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
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 index, partLen;
226 	size_t i;
227 
228 	/* Compute number of bytes mod 64 */
229 	index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
230 
231 	/* Update number of bits */
232 	if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
233 		context->count[1]++;
234 	}
235 	context->count[1] += (uint32_t) (inputLen >> 29);
236 
237 	partLen = 64 - index;
238 
239 	/* Transform as many times as possible.
240 	 */
241 	if (inputLen >= partLen) {
242 		memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
243 		SHA256Transform(context->state, context->buffer);
244 
245 		for (i = partLen; i + 63 < inputLen; i += 64) {
246 			SHA256Transform(context->state, &input[i]);
247 		}
248 
249 		index = 0;
250 	} else {
251 		i = 0;
252 	}
253 
254 	/* Buffer remaining input */
255 	memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
256 }
257 /* }}} */
258 
259 /* {{{ PHP_SHA224Final
260    SHA224 finalization. Ends an SHA224 message-digest operation, writing the
261    the message digest and zeroizing the context.
262  */
PHP_SHA224Final(unsigned char digest[28],PHP_SHA224_CTX * context)263 PHP_HASH_API void PHP_SHA224Final(unsigned char digest[28], PHP_SHA224_CTX * context)
264 {
265 	unsigned char bits[8];
266 	unsigned int index, padLen;
267 
268 	/* Save number of bits */
269 	bits[7] = (unsigned char) (context->count[0] & 0xFF);
270 	bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
271 	bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
272 	bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
273 	bits[3] = (unsigned char) (context->count[1] & 0xFF);
274 	bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
275 	bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
276 	bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
277 
278 	/* Pad out to 56 mod 64.
279 	 */
280 	index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
281 	padLen = (index < 56) ? (56 - index) : (120 - index);
282 	PHP_SHA224Update(context, PADDING, padLen);
283 
284 	/* Append length (before padding) */
285 	PHP_SHA224Update(context, bits, 8);
286 
287 	/* Store state in digest */
288 	SHAEncode32(digest, context->state, 28);
289 
290 	/* Zeroize sensitive information.
291 	 */
292 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
293 }
294 /* }}} */
295 
296 /* {{{ PHP_SHA256Update
297    SHA256 block update operation. Continues an SHA256 message-digest
298    operation, processing another message block, and updating the
299    context.
300  */
PHP_SHA256Update(PHP_SHA256_CTX * context,const unsigned char * input,size_t inputLen)301 PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, size_t inputLen)
302 {
303 	unsigned int index, partLen;
304 	size_t i;
305 
306 	/* Compute number of bytes mod 64 */
307 	index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
308 
309 	/* Update number of bits */
310 	if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
311 		context->count[1]++;
312 	}
313 	context->count[1] += (uint32_t) (inputLen >> 29);
314 
315 	partLen = 64 - index;
316 
317 	/* Transform as many times as possible.
318 	 */
319 	if (inputLen >= partLen) {
320 		memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
321 		SHA256Transform(context->state, context->buffer);
322 
323 		for (i = partLen; i + 63 < inputLen; i += 64) {
324 			SHA256Transform(context->state, &input[i]);
325 		}
326 
327 		index = 0;
328 	} else {
329 		i = 0;
330 	}
331 
332 	/* Buffer remaining input */
333 	memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
334 }
335 /* }}} */
336 
337 /* {{{ PHP_SHA256Final
338    SHA256 finalization. Ends an SHA256 message-digest operation, writing the
339    the message digest and zeroizing the context.
340  */
PHP_SHA256Final(unsigned char digest[32],PHP_SHA256_CTX * context)341 PHP_HASH_API void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
342 {
343 	unsigned char bits[8];
344 	unsigned int index, padLen;
345 
346 	/* Save number of bits */
347 	bits[7] = (unsigned char) (context->count[0] & 0xFF);
348 	bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
349 	bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
350 	bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
351 	bits[3] = (unsigned char) (context->count[1] & 0xFF);
352 	bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
353 	bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
354 	bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
355 
356 	/* Pad out to 56 mod 64.
357 	 */
358 	index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
359 	padLen = (index < 56) ? (56 - index) : (120 - index);
360 	PHP_SHA256Update(context, PADDING, padLen);
361 
362 	/* Append length (before padding) */
363 	PHP_SHA256Update(context, bits, 8);
364 
365 	/* Store state in digest */
366 	SHAEncode32(digest, context->state, 32);
367 
368 	/* Zeroize sensitive information.
369 	 */
370 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
371 }
372 /* }}} */
373 
374 /* sha384/sha512 */
375 
376 /* Ch */
377 #define SHA512_F0(x,y,z)		(((x) & (y)) ^ ((~(x)) & (z)))
378 /* Maj */
379 #define SHA512_F1(x,y,z)		(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
380 /* SUM0 */
381 #define SHA512_F2(x)			(ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x))
382 /* SUM1 */
383 #define SHA512_F3(x)			(ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x))
384 /* OM0 */
385 #define SHA512_F4(x)			(ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR(7, x))
386 /* OM1 */
387 #define SHA512_F5(x)			(ROTR64(19, x) ^ ROTR64(61, x) ^ SHR(6, x))
388 
389 static const uint64_t SHA512_K[128] = {
390 	L64(0x428a2f98d728ae22), L64(0x7137449123ef65cd), L64(0xb5c0fbcfec4d3b2f), L64(0xe9b5dba58189dbbc),
391 	L64(0x3956c25bf348b538), L64(0x59f111f1b605d019), L64(0x923f82a4af194f9b), L64(0xab1c5ed5da6d8118),
392 	L64(0xd807aa98a3030242), L64(0x12835b0145706fbe), L64(0x243185be4ee4b28c), L64(0x550c7dc3d5ffb4e2),
393 	L64(0x72be5d74f27b896f), L64(0x80deb1fe3b1696b1), L64(0x9bdc06a725c71235), L64(0xc19bf174cf692694),
394 	L64(0xe49b69c19ef14ad2), L64(0xefbe4786384f25e3), L64(0x0fc19dc68b8cd5b5), L64(0x240ca1cc77ac9c65),
395 	L64(0x2de92c6f592b0275), L64(0x4a7484aa6ea6e483), L64(0x5cb0a9dcbd41fbd4), L64(0x76f988da831153b5),
396 	L64(0x983e5152ee66dfab), L64(0xa831c66d2db43210), L64(0xb00327c898fb213f), L64(0xbf597fc7beef0ee4),
397 	L64(0xc6e00bf33da88fc2), L64(0xd5a79147930aa725), L64(0x06ca6351e003826f), L64(0x142929670a0e6e70),
398 	L64(0x27b70a8546d22ffc), L64(0x2e1b21385c26c926), L64(0x4d2c6dfc5ac42aed), L64(0x53380d139d95b3df),
399 	L64(0x650a73548baf63de), L64(0x766a0abb3c77b2a8), L64(0x81c2c92e47edaee6), L64(0x92722c851482353b),
400 	L64(0xa2bfe8a14cf10364), L64(0xa81a664bbc423001), L64(0xc24b8b70d0f89791), L64(0xc76c51a30654be30),
401 	L64(0xd192e819d6ef5218), L64(0xd69906245565a910), L64(0xf40e35855771202a), L64(0x106aa07032bbd1b8),
402 	L64(0x19a4c116b8d2d0c8), L64(0x1e376c085141ab53), L64(0x2748774cdf8eeb99), L64(0x34b0bcb5e19b48a8),
403 	L64(0x391c0cb3c5c95a63), L64(0x4ed8aa4ae3418acb), L64(0x5b9cca4f7763e373), L64(0x682e6ff3d6b2b8a3),
404 	L64(0x748f82ee5defb2fc), L64(0x78a5636f43172f60), L64(0x84c87814a1f0ab72), L64(0x8cc702081a6439ec),
405 	L64(0x90befffa23631e28), L64(0xa4506cebde82bde9), L64(0xbef9a3f7b2c67915), L64(0xc67178f2e372532b),
406 	L64(0xca273eceea26619c), L64(0xd186b8c721c0c207), L64(0xeada7dd6cde0eb1e), L64(0xf57d4f7fee6ed178),
407 	L64(0x06f067aa72176fba), L64(0x0a637dc5a2c898a6), L64(0x113f9804bef90dae), L64(0x1b710b35131c471b),
408 	L64(0x28db77f523047d84), L64(0x32caab7b40c72493), L64(0x3c9ebe0a15c9bebc), L64(0x431d67c49c100d4c),
409 	L64(0x4cc5d4becb3e42b6), L64(0x597f299cfc657e2a), L64(0x5fcb6fab3ad6faec), L64(0x6c44198c4a475817) };
410 
411 /* {{{ SHAEncode64
412    Encodes input (uint64_t) into output (unsigned char). Assumes len is
413    a multiple of 8.
414  */
SHAEncode64(unsigned char * output,uint64_t * input,unsigned int len)415 static void SHAEncode64(unsigned char *output, uint64_t *input, unsigned int len)
416 {
417 	unsigned int i, j;
418 
419 	for (i = 0, j = 0; j < len; i++, j += 8) {
420 		output[j] = (unsigned char) ((input[i] >> 56) & 0xff);
421 		output[j + 1] = (unsigned char) ((input[i] >> 48) & 0xff);
422 		output[j + 2] = (unsigned char) ((input[i] >> 40) & 0xff);
423 		output[j + 3] = (unsigned char) ((input[i] >> 32) & 0xff);
424 		output[j + 4] = (unsigned char) ((input[i] >> 24) & 0xff);
425 		output[j + 5] = (unsigned char) ((input[i] >> 16) & 0xff);
426 		output[j + 6] = (unsigned char) ((input[i] >> 8) & 0xff);
427 		output[j + 7] = (unsigned char) (input[i] & 0xff);
428 	}
429 }
430 /* }}} */
431 
432 
433 /* {{{ SHADecode64
434    Decodes input (unsigned char) into output (uint64_t). Assumes len is
435    a multiple of 8.
436  */
SHADecode64(uint64_t * output,const unsigned char * input,unsigned int len)437 static void SHADecode64(uint64_t *output, const unsigned char *input, unsigned int len)
438 {
439 	unsigned int i, j;
440 
441 	for (i = 0, j = 0; j < len; i++, j += 8)
442 		output[i] =
443 			((uint64_t) input[j + 7]) | (((uint64_t) input[j + 6]) << 8) |
444 			(((uint64_t) input[j + 5]) << 16) | (((uint64_t) input[j + 4]) << 24) |
445 			(((uint64_t) input[j + 3]) << 32) | (((uint64_t) input[j + 2]) << 40) |
446 			(((uint64_t) input[j + 1]) << 48) | (((uint64_t) input[j]) << 56);
447 }
448 /* }}} */
449 
450 /* {{{ PHP_SHA384InitArgs
451  * SHA384 initialization. Begins an SHA384 operation, writing a new context.
452  */
PHP_SHA384InitArgs(PHP_SHA384_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)453 PHP_HASH_API void PHP_SHA384InitArgs(PHP_SHA384_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
454 {
455 	context->count[0] = context->count[1] = 0;
456 	/* Load magic initialization constants.
457 	 */
458 	context->state[0] = L64(0xcbbb9d5dc1059ed8);
459 	context->state[1] = L64(0x629a292a367cd507);
460 	context->state[2] = L64(0x9159015a3070dd17);
461 	context->state[3] = L64(0x152fecd8f70e5939);
462 	context->state[4] = L64(0x67332667ffc00b31);
463 	context->state[5] = L64(0x8eb44a8768581511);
464 	context->state[6] = L64(0xdb0c2e0d64f98fa7);
465 	context->state[7] = L64(0x47b5481dbefa4fa4);
466 }
467 /* }}} */
468 
469 /* {{{ SHA512Transform
470  * SHA512 basic transformation. Transforms state based on block.
471  * SHA384 uses the exact same algorithm
472  */
SHA512Transform(uint64_t state[8],const unsigned char block[128])473 static void SHA512Transform(uint64_t state[8], const unsigned char block[128])
474 {
475 	uint64_t a = state[0], b = state[1], c = state[2], d = state[3];
476 	uint64_t e = state[4], f = state[5], g = state[6], h = state[7];
477 	uint64_t x[16], T1, T2, W[80];
478 	int i;
479 
480 	SHADecode64(x, block, 128);
481 
482 	/* Schedule */
483 	for(i = 0; i < 16; i++) {
484 		W[i] = x[i];
485 	}
486 	for(i = 16; i < 80; i++) {
487 		W[i] = SHA512_F5(W[i-2]) + W[i-7] + SHA512_F4(W[i-15]) + W[i-16];
488 	}
489 
490 	for (i = 0; i < 80; i++) {
491 		T1 = h + SHA512_F3(e) + SHA512_F0(e,f,g) + SHA512_K[i] + W[i];
492 		T2 = SHA512_F2(a) + SHA512_F1(a,b,c);
493 		h = g; g = f; f = e; e = d + T1;
494 		d = c; c = b; b = a; a = T1 + T2;
495 	}
496 
497 	state[0] += a;
498 	state[1] += b;
499 	state[2] += c;
500 	state[3] += d;
501 	state[4] += e;
502 	state[5] += f;
503 	state[6] += g;
504 	state[7] += h;
505 
506 	/* Zeroize sensitive information. */
507 	ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
508 }
509 /* }}} */
510 
511 /* {{{ PHP_SHA384Update
512    SHA384 block update operation. Continues an SHA384 message-digest
513    operation, processing another message block, and updating the
514    context.
515  */
PHP_SHA384Update(PHP_SHA384_CTX * context,const unsigned char * input,size_t inputLen)516 PHP_HASH_API void PHP_SHA384Update(PHP_SHA384_CTX * context, const unsigned char *input, size_t inputLen)
517 {
518 	unsigned int index, partLen;
519 	size_t i = 0;
520 
521 	/* Compute number of bytes mod 128 */
522 	index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
523 
524 	/* Update number of bits */
525 	if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
526 		context->count[1]++;
527 	}
528 	/* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
529 	context->count[1] += (uint64_t) inputLen >> 61;
530 
531 	partLen = 128 - index;
532 
533 	/* Transform as many times as possible.
534 	 */
535 	if (inputLen >= partLen) {
536 		memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
537 		SHA512Transform(context->state, context->buffer);
538 
539 		for (i = partLen; i + 127 < inputLen; i += 128) {
540 			SHA512Transform(context->state, &input[i]);
541 		}
542 
543 		index = 0;
544 	}
545 
546 	/* Buffer remaining input */
547 	memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
548 }
549 /* }}} */
550 
551 /* {{{ PHP_SHA384Final
552    SHA384 finalization. Ends an SHA384 message-digest operation, writing the
553    the message digest and zeroizing the context.
554  */
PHP_SHA384Final(unsigned char digest[48],PHP_SHA384_CTX * context)555 PHP_HASH_API void PHP_SHA384Final(unsigned char digest[48], PHP_SHA384_CTX * context)
556 {
557 	unsigned char bits[16];
558 	unsigned int index, padLen;
559 
560 	/* Save number of bits */
561 	bits[15] = (unsigned char) (context->count[0] & 0xFF);
562 	bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
563 	bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
564 	bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
565 	bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
566 	bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
567 	bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
568 	bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
569 	bits[7]  = (unsigned char) (context->count[1] & 0xFF);
570 	bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
571 	bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
572 	bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
573 	bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
574 	bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
575 	bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
576 	bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
577 
578 	/* Pad out to 112 mod 128.
579 	 */
580 	index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
581 	padLen = (index < 112) ? (112 - index) : (240 - index);
582 	PHP_SHA384Update(context, PADDING, padLen);
583 
584 	/* Append length (before padding) */
585 	PHP_SHA384Update(context, bits, 16);
586 
587 	/* Store state in digest */
588 	SHAEncode64(digest, context->state, 48);
589 
590 	/* Zeroize sensitive information.
591 	 */
592 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
593 }
594 /* }}} */
595 
596 const php_hash_ops php_hash_sha384_ops = {
597 	"sha384",
598 	(php_hash_init_func_t) PHP_SHA384InitArgs,
599 	(php_hash_update_func_t) PHP_SHA384Update,
600 	(php_hash_final_func_t) PHP_SHA384Final,
601 	php_hash_copy,
602 	php_hash_serialize,
603 	php_hash_unserialize,
604 	PHP_SHA384_SPEC,
605 	48,
606 	128,
607 	sizeof(PHP_SHA384_CTX),
608 	1
609 };
610 
611 /* {{{ PHP_SHA512InitArgs
612  * SHA512 initialization. Begins an SHA512 operation, writing a new context.
613  */
PHP_SHA512InitArgs(PHP_SHA512_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)614 PHP_HASH_API void PHP_SHA512InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
615 {
616 	context->count[0] = context->count[1] = 0;
617 	/* Load magic initialization constants.
618 	 */
619 	context->state[0] = L64(0x6a09e667f3bcc908);
620 	context->state[1] = L64(0xbb67ae8584caa73b);
621 	context->state[2] = L64(0x3c6ef372fe94f82b);
622 	context->state[3] = L64(0xa54ff53a5f1d36f1);
623 	context->state[4] = L64(0x510e527fade682d1);
624 	context->state[5] = L64(0x9b05688c2b3e6c1f);
625 	context->state[6] = L64(0x1f83d9abfb41bd6b);
626 	context->state[7] = L64(0x5be0cd19137e2179);
627 }
628 /* }}} */
629 
630 /* {{{ PHP_SHA512_256InitArgs
631  * SHA512/245 initialization. Identical algorithm to SHA512, using alternate initval and truncation
632  */
PHP_SHA512_256InitArgs(PHP_SHA512_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)633 PHP_HASH_API void PHP_SHA512_256InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
634 {
635 	context->count[0] = context->count[1] = 0;
636 
637 	context->state[0] = L64(0x22312194FC2BF72C);
638 	context->state[1] = L64(0x9F555FA3C84C64C2);
639 	context->state[2] = L64(0x2393B86B6F53B151);
640 	context->state[3] = L64(0x963877195940EABD);
641 	context->state[4] = L64(0x96283EE2A88EFFE3);
642 	context->state[5] = L64(0xBE5E1E2553863992);
643 	context->state[6] = L64(0x2B0199FC2C85B8AA);
644 	context->state[7] = L64(0x0EB72DDC81C52CA2);
645 }
646 /* }}} */
647 
648 /* {{{ PHP_SHA512_224InitArgs
649  * SHA512/224 initialization. Identical algorithm to SHA512, using alternate initval and truncation
650  */
PHP_SHA512_224InitArgs(PHP_SHA512_CTX * context,ZEND_ATTRIBUTE_UNUSED HashTable * args)651 PHP_HASH_API void PHP_SHA512_224InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
652 {
653         context->count[0] = context->count[1] = 0;
654 
655 	context->state[0] = L64(0x8C3D37C819544DA2);
656 	context->state[1] = L64(0x73E1996689DCD4D6);
657 	context->state[2] = L64(0x1DFAB7AE32FF9C82);
658 	context->state[3] = L64(0x679DD514582F9FCF);
659 	context->state[4] = L64(0x0F6D2B697BD44DA8);
660 	context->state[5] = L64(0x77E36F7304C48942);
661 	context->state[6] = L64(0x3F9D85A86A1D36C8);
662 	context->state[7] = L64(0x1112E6AD91D692A1);
663 }
664 /* }}} */
665 
666 /* {{{ PHP_SHA512Update
667    SHA512 block update operation. Continues an SHA512 message-digest
668    operation, processing another message block, and updating the
669    context.
670  */
PHP_SHA512Update(PHP_SHA512_CTX * context,const unsigned char * input,size_t inputLen)671 PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX * context, const unsigned char *input, size_t inputLen)
672 {
673 	unsigned int index, partLen;
674 	size_t i;
675 
676 	/* Compute number of bytes mod 128 */
677 	index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
678 
679 	/* Update number of bits */
680 	if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
681 		context->count[1]++;
682 	}
683 	/* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
684 	context->count[1] += (uint64_t) inputLen >> 61;
685 
686 	partLen = 128 - index;
687 
688 	/* Transform as many times as possible.
689 	 */
690 	if (inputLen >= partLen) {
691 		memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
692 		SHA512Transform(context->state, context->buffer);
693 
694 		for (i = partLen; i + 127 < inputLen; i += 128) {
695 			SHA512Transform(context->state, &input[i]);
696 		}
697 
698 		index = 0;
699 	} else {
700 		i = 0;
701 	}
702 
703 	/* Buffer remaining input */
704 	memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
705 }
706 /* }}} */
707 
708 /* {{{ PHP_SHA512Final
709    SHA512 finalization. Ends an SHA512 message-digest operation, writing the
710    the message digest and zeroizing the context.
711  */
PHP_SHA512Final(unsigned char digest[64],PHP_SHA512_CTX * context)712 PHP_HASH_API void PHP_SHA512Final(unsigned char digest[64], PHP_SHA512_CTX * context)
713 {
714 	unsigned char bits[16];
715 	unsigned int index, padLen;
716 
717 	/* Save number of bits */
718 	bits[15] = (unsigned char) (context->count[0] & 0xFF);
719 	bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
720 	bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
721 	bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
722 	bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
723 	bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
724 	bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
725 	bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
726 	bits[7]  = (unsigned char) (context->count[1] & 0xFF);
727 	bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
728 	bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
729 	bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
730 	bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
731 	bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
732 	bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
733 	bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
734 
735 	/* Pad out to 112 mod 128.
736 	 */
737 	index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
738 	padLen = (index < 112) ? (112 - index) : (240 - index);
739 	PHP_SHA512Update(context, PADDING, padLen);
740 
741 	/* Append length (before padding) */
742 	PHP_SHA512Update(context, bits, 16);
743 
744 	/* Store state in digest */
745 	SHAEncode64(digest, context->state, 64);
746 
747 	/* Zeroize sensitive information.
748 	 */
749 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
750 }
751 /* }}} */
752 
753 /* {{{ PHP_SHA512_256Final
754    SHA512/256 finalization. Identical to SHA512Final, but with truncation
755  */
PHP_SHA512_256Final(unsigned char digest[32],PHP_SHA512_CTX * context)756 PHP_HASH_API void PHP_SHA512_256Final(unsigned char digest[32], PHP_SHA512_CTX * context)
757 {
758 	unsigned char full_digest[64];
759 	PHP_SHA512Final(full_digest, context);
760 	memcpy(digest, full_digest, 32);
761 }
762 /* }}} */
763 
764 /* {{{ PHP_SHA512_224Final
765    SHA512/224 finalization. Identical to SHA512Final, but with truncation
766  */
PHP_SHA512_224Final(unsigned char digest[28],PHP_SHA512_CTX * context)767 PHP_HASH_API void PHP_SHA512_224Final(unsigned char digest[28], PHP_SHA512_CTX * context)
768 {
769 	unsigned char full_digest[64];
770 	PHP_SHA512Final(full_digest, context);
771 	memcpy(digest, full_digest, 28);
772 }
773 /* }}} */
774 
775 const php_hash_ops php_hash_sha512_ops = {
776 	"sha512",
777 	(php_hash_init_func_t) PHP_SHA512InitArgs,
778 	(php_hash_update_func_t) PHP_SHA512Update,
779 	(php_hash_final_func_t) PHP_SHA512Final,
780 	php_hash_copy,
781 	php_hash_serialize,
782 	php_hash_unserialize,
783 	PHP_SHA512_SPEC,
784 	64,
785 	128,
786 	sizeof(PHP_SHA512_CTX),
787 	1
788 };
789 
790 const php_hash_ops php_hash_sha512_256_ops = {
791 	"sha512/256",
792 	(php_hash_init_func_t) PHP_SHA512_256InitArgs,
793 	(php_hash_update_func_t) PHP_SHA512_256Update,
794 	(php_hash_final_func_t) PHP_SHA512_256Final,
795 	php_hash_copy,
796 	php_hash_serialize,
797 	php_hash_unserialize,
798 	PHP_SHA512_SPEC,
799 	32,
800 	128,
801 	sizeof(PHP_SHA512_CTX),
802 	1
803 };
804 
805 const php_hash_ops php_hash_sha512_224_ops = {
806 	"sha512/224",
807 	(php_hash_init_func_t) PHP_SHA512_224InitArgs,
808 	(php_hash_update_func_t) PHP_SHA512_224Update,
809 	(php_hash_final_func_t) PHP_SHA512_224Final,
810 	php_hash_copy,
811 	php_hash_serialize,
812 	php_hash_unserialize,
813 	PHP_SHA512_SPEC,
814 	28,
815 	128,
816 	sizeof(PHP_SHA512_CTX),
817 	1
818 };
819