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