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