1 | /* |
2 | +----------------------------------------------------------------------+ |
3 | | PHP Version 5 | |
4 | +----------------------------------------------------------------------+ |
5 | | Copyright (c) 1997-2015 The PHP Group | |
6 | +----------------------------------------------------------------------+ |
7 | | This source file is subject to version 3.01 of the PHP license, | |
8 | | that is bundled with this package in the file LICENSE, and is | |
9 | | available through the world-wide-web at the following url: | |
10 | | http://www.php.net/license/3_01.txt | |
11 | | If you did not receive a copy of the PHP license and are unable to | |
12 | | obtain it through the world-wide-web, please send a note to | |
13 | | license@php.net so we can mail you a copy immediately. | |
14 | +----------------------------------------------------------------------+ |
15 | | Authors: Steffan Esser <sesser@php.net> | |
16 | | Sara Golemon <pollita@php.net> | |
17 | +----------------------------------------------------------------------+ |
18 | */ |
19 | |
20 | /* $Id$ */ |
21 | |
22 | #include "php_hash.h" |
23 | #include "php_hash_sha.h" |
24 | |
25 | static const unsigned char PADDING[128] = |
26 | { |
27 | 0x80, 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 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
34 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
35 | }; |
36 | |
37 | /* {{{ SHAEncode32 |
38 | Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is |
39 | a multiple of 4. |
40 | */ |
41 | static void SHAEncode32(unsigned char *output, php_hash_uint32 *input, unsigned int len) |
42 | { |
43 | unsigned int i, j; |
44 | |
45 | for (i = 0, j = 0; j < len; i++, j += 4) { |
46 | output[j] = (unsigned char) ((input[i] >> 24) & 0xff); |
47 | output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); |
48 | output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); |
49 | output[j + 3] = (unsigned char) (input[i] & 0xff); |
50 | } |
51 | } |
52 | /* }}} */ |
53 | |
54 | |
55 | /* {{{ SHADecode32 |
56 | Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is |
57 | a multiple of 4. |
58 | */ |
59 | static void SHADecode32(php_hash_uint32 *output, const unsigned char *input, unsigned int len) |
60 | { |
61 | unsigned int i, j; |
62 | |
63 | for (i = 0, j = 0; j < len; i++, j += 4) |
64 | output[i] = ((php_hash_uint32) input[j + 3]) | (((php_hash_uint32) input[j + 2]) << 8) | |
65 | (((php_hash_uint32) input[j + 1]) << 16) | (((php_hash_uint32) input[j]) << 24); |
66 | } |
67 | /* }}} */ |
68 | |
69 | const php_hash_ops php_hash_sha1_ops = { |
70 | (php_hash_init_func_t) PHP_SHA1Init, |
71 | (php_hash_update_func_t) PHP_SHA1Update, |
72 | (php_hash_final_func_t) PHP_SHA1Final, |
73 | (php_hash_copy_func_t) php_hash_copy, |
74 | 20, |
75 | 64, |
76 | sizeof(PHP_SHA1_CTX) |
77 | }; |
78 | |
79 | #ifdef PHP_HASH_SHA1_NOT_IN_CORE |
80 | |
81 | PHP_HASH_API void make_sha1_digest(char *sha1str, unsigned char *digest) |
82 | { |
83 | php_hash_bin2hex(sha1str, digest, 20); |
84 | sha1str[40] = '\0'; |
85 | } |
86 | |
87 | /* {{{ proto string sha1(string str [, bool raw_output]) |
88 | Calculate the sha1 hash of a string */ |
89 | PHP_FUNCTION(sha1) |
90 | { |
91 | char *arg; |
92 | int arg_len; |
93 | zend_bool raw_output = 0; |
94 | char sha1str[41]; |
95 | PHP_SHA1_CTX context; |
96 | unsigned char digest[20]; |
97 | |
98 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b" , &arg, &arg_len, &raw_output) == FAILURE) { |
99 | return; |
100 | } |
101 | |
102 | sha1str[0] = '\0'; |
103 | PHP_SHA1Init(&context); |
104 | PHP_SHA1Update(&context, arg, arg_len); |
105 | PHP_SHA1Final(digest, &context); |
106 | if (raw_output) { |
107 | RETURN_STRINGL(digest, 20, 1); |
108 | } else { |
109 | make_sha1_digest(sha1str, digest); |
110 | RETVAL_STRING(sha1str, 1); |
111 | } |
112 | |
113 | } |
114 | |
115 | /* }}} */ |
116 | |
117 | /* {{{ proto string sha1_file(string filename [, bool raw_output]) |
118 | Calculate the sha1 hash of given filename */ |
119 | PHP_FUNCTION(sha1_file) |
120 | { |
121 | char *arg; |
122 | int arg_len; |
123 | zend_bool raw_output = 0; |
124 | char sha1str[41]; |
125 | unsigned char buf[1024]; |
126 | unsigned char digest[20]; |
127 | PHP_SHA1_CTX context; |
128 | int n; |
129 | php_stream *stream; |
130 | |
131 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|b" , &arg, &arg_len, &raw_output) == FAILURE) { |
132 | return; |
133 | } |
134 | |
135 | stream = php_stream_open_wrapper(arg, "rb" , REPORT_ERRORS, NULL); |
136 | if (!stream) { |
137 | RETURN_FALSE; |
138 | } |
139 | |
140 | PHP_SHA1Init(&context); |
141 | |
142 | while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { |
143 | PHP_SHA1Update(&context, buf, n); |
144 | } |
145 | |
146 | PHP_SHA1Final(digest, &context); |
147 | |
148 | php_stream_close(stream); |
149 | |
150 | if (n<0) { |
151 | RETURN_FALSE; |
152 | } |
153 | |
154 | if (raw_output) { |
155 | RETURN_STRINGL(digest, 20, 1); |
156 | } else { |
157 | make_sha1_digest(sha1str, digest); |
158 | RETVAL_STRING(sha1str, 1); |
159 | } |
160 | } |
161 | /* }}} */ |
162 | |
163 | /* F, G, H and I are basic SHA1 functions. |
164 | */ |
165 | #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) |
166 | #define G(x, y, z) ((x) ^ (y) ^ (z)) |
167 | #define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) |
168 | #define I(x, y, z) ((x) ^ (y) ^ (z)) |
169 | |
170 | /* ROTATE_LEFT rotates x left n bits. |
171 | */ |
172 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) |
173 | |
174 | /* W[i] |
175 | */ |
176 | #define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \ |
177 | (x[i&15]=ROTATE_LEFT(tmp, 1)) ) |
178 | |
179 | /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. |
180 | */ |
181 | #define FF(a, b, c, d, e, w) { \ |
182 | (e) += F ((b), (c), (d)) + (w) + (php_hash_uint32)(0x5A827999); \ |
183 | (e) += ROTATE_LEFT ((a), 5); \ |
184 | (b) = ROTATE_LEFT((b), 30); \ |
185 | } |
186 | #define GG(a, b, c, d, e, w) { \ |
187 | (e) += G ((b), (c), (d)) + (w) + (php_hash_uint32)(0x6ED9EBA1); \ |
188 | (e) += ROTATE_LEFT ((a), 5); \ |
189 | (b) = ROTATE_LEFT((b), 30); \ |
190 | } |
191 | #define HH(a, b, c, d, e, w) { \ |
192 | (e) += H ((b), (c), (d)) + (w) + (php_hash_uint32)(0x8F1BBCDC); \ |
193 | (e) += ROTATE_LEFT ((a), 5); \ |
194 | (b) = ROTATE_LEFT((b), 30); \ |
195 | } |
196 | #define II(a, b, c, d, e, w) { \ |
197 | (e) += I ((b), (c), (d)) + (w) + (php_hash_uint32)(0xCA62C1D6); \ |
198 | (e) += ROTATE_LEFT ((a), 5); \ |
199 | (b) = ROTATE_LEFT((b), 30); \ |
200 | } |
201 | |
202 | |
203 | /* {{{ PHP_SHA1Init |
204 | * SHA1 initialization. Begins an SHA1 operation, writing a new context. |
205 | */ |
206 | PHP_HASH_API void PHP_SHA1Init(PHP_SHA1_CTX * context) |
207 | { |
208 | context->count[0] = context->count[1] = 0; |
209 | /* Load magic initialization constants. |
210 | */ |
211 | context->state[0] = 0x67452301; |
212 | context->state[1] = 0xefcdab89; |
213 | context->state[2] = 0x98badcfe; |
214 | context->state[3] = 0x10325476; |
215 | context->state[4] = 0xc3d2e1f0; |
216 | } |
217 | /* }}} */ |
218 | |
219 | /* {{{ SHA1Transform |
220 | * SHA1 basic transformation. Transforms state based on block. |
221 | */ |
222 | static void SHA1Transform(php_hash_uint32 state[5], const unsigned char block[64]) |
223 | { |
224 | php_hash_uint32 a = state[0], b = state[1], c = state[2]; |
225 | php_hash_uint32 d = state[3], e = state[4], x[16], tmp; |
226 | |
227 | SHADecode32(x, block, 64); |
228 | |
229 | /* Round 1 */ |
230 | FF(a, b, c, d, e, x[0]); /* 1 */ |
231 | FF(e, a, b, c, d, x[1]); /* 2 */ |
232 | FF(d, e, a, b, c, x[2]); /* 3 */ |
233 | FF(c, d, e, a, b, x[3]); /* 4 */ |
234 | FF(b, c, d, e, a, x[4]); /* 5 */ |
235 | FF(a, b, c, d, e, x[5]); /* 6 */ |
236 | FF(e, a, b, c, d, x[6]); /* 7 */ |
237 | FF(d, e, a, b, c, x[7]); /* 8 */ |
238 | FF(c, d, e, a, b, x[8]); /* 9 */ |
239 | FF(b, c, d, e, a, x[9]); /* 10 */ |
240 | FF(a, b, c, d, e, x[10]); /* 11 */ |
241 | FF(e, a, b, c, d, x[11]); /* 12 */ |
242 | FF(d, e, a, b, c, x[12]); /* 13 */ |
243 | FF(c, d, e, a, b, x[13]); /* 14 */ |
244 | FF(b, c, d, e, a, x[14]); /* 15 */ |
245 | FF(a, b, c, d, e, x[15]); /* 16 */ |
246 | FF(e, a, b, c, d, W(16)); /* 17 */ |
247 | FF(d, e, a, b, c, W(17)); /* 18 */ |
248 | FF(c, d, e, a, b, W(18)); /* 19 */ |
249 | FF(b, c, d, e, a, W(19)); /* 20 */ |
250 | |
251 | /* Round 2 */ |
252 | GG(a, b, c, d, e, W(20)); /* 21 */ |
253 | GG(e, a, b, c, d, W(21)); /* 22 */ |
254 | GG(d, e, a, b, c, W(22)); /* 23 */ |
255 | GG(c, d, e, a, b, W(23)); /* 24 */ |
256 | GG(b, c, d, e, a, W(24)); /* 25 */ |
257 | GG(a, b, c, d, e, W(25)); /* 26 */ |
258 | GG(e, a, b, c, d, W(26)); /* 27 */ |
259 | GG(d, e, a, b, c, W(27)); /* 28 */ |
260 | GG(c, d, e, a, b, W(28)); /* 29 */ |
261 | GG(b, c, d, e, a, W(29)); /* 30 */ |
262 | GG(a, b, c, d, e, W(30)); /* 31 */ |
263 | GG(e, a, b, c, d, W(31)); /* 32 */ |
264 | GG(d, e, a, b, c, W(32)); /* 33 */ |
265 | GG(c, d, e, a, b, W(33)); /* 34 */ |
266 | GG(b, c, d, e, a, W(34)); /* 35 */ |
267 | GG(a, b, c, d, e, W(35)); /* 36 */ |
268 | GG(e, a, b, c, d, W(36)); /* 37 */ |
269 | GG(d, e, a, b, c, W(37)); /* 38 */ |
270 | GG(c, d, e, a, b, W(38)); /* 39 */ |
271 | GG(b, c, d, e, a, W(39)); /* 40 */ |
272 | |
273 | /* Round 3 */ |
274 | HH(a, b, c, d, e, W(40)); /* 41 */ |
275 | HH(e, a, b, c, d, W(41)); /* 42 */ |
276 | HH(d, e, a, b, c, W(42)); /* 43 */ |
277 | HH(c, d, e, a, b, W(43)); /* 44 */ |
278 | HH(b, c, d, e, a, W(44)); /* 45 */ |
279 | HH(a, b, c, d, e, W(45)); /* 46 */ |
280 | HH(e, a, b, c, d, W(46)); /* 47 */ |
281 | HH(d, e, a, b, c, W(47)); /* 48 */ |
282 | HH(c, d, e, a, b, W(48)); /* 49 */ |
283 | HH(b, c, d, e, a, W(49)); /* 50 */ |
284 | HH(a, b, c, d, e, W(50)); /* 51 */ |
285 | HH(e, a, b, c, d, W(51)); /* 52 */ |
286 | HH(d, e, a, b, c, W(52)); /* 53 */ |
287 | HH(c, d, e, a, b, W(53)); /* 54 */ |
288 | HH(b, c, d, e, a, W(54)); /* 55 */ |
289 | HH(a, b, c, d, e, W(55)); /* 56 */ |
290 | HH(e, a, b, c, d, W(56)); /* 57 */ |
291 | HH(d, e, a, b, c, W(57)); /* 58 */ |
292 | HH(c, d, e, a, b, W(58)); /* 59 */ |
293 | HH(b, c, d, e, a, W(59)); /* 60 */ |
294 | |
295 | /* Round 4 */ |
296 | II(a, b, c, d, e, W(60)); /* 61 */ |
297 | II(e, a, b, c, d, W(61)); /* 62 */ |
298 | II(d, e, a, b, c, W(62)); /* 63 */ |
299 | II(c, d, e, a, b, W(63)); /* 64 */ |
300 | II(b, c, d, e, a, W(64)); /* 65 */ |
301 | II(a, b, c, d, e, W(65)); /* 66 */ |
302 | II(e, a, b, c, d, W(66)); /* 67 */ |
303 | II(d, e, a, b, c, W(67)); /* 68 */ |
304 | II(c, d, e, a, b, W(68)); /* 69 */ |
305 | II(b, c, d, e, a, W(69)); /* 70 */ |
306 | II(a, b, c, d, e, W(70)); /* 71 */ |
307 | II(e, a, b, c, d, W(71)); /* 72 */ |
308 | II(d, e, a, b, c, W(72)); /* 73 */ |
309 | II(c, d, e, a, b, W(73)); /* 74 */ |
310 | II(b, c, d, e, a, W(74)); /* 75 */ |
311 | II(a, b, c, d, e, W(75)); /* 76 */ |
312 | II(e, a, b, c, d, W(76)); /* 77 */ |
313 | II(d, e, a, b, c, W(77)); /* 78 */ |
314 | II(c, d, e, a, b, W(78)); /* 79 */ |
315 | II(b, c, d, e, a, W(79)); /* 80 */ |
316 | |
317 | state[0] += a; |
318 | state[1] += b; |
319 | state[2] += c; |
320 | state[3] += d; |
321 | state[4] += e; |
322 | |
323 | /* Zeroize sensitive information. */ |
324 | memset((unsigned char*) x, 0, sizeof(x)); |
325 | } |
326 | /* }}} */ |
327 | |
328 | /* {{{ PHP_SHA1Update |
329 | SHA1 block update operation. Continues an SHA1 message-digest |
330 | operation, processing another message block, and updating the |
331 | context. |
332 | */ |
333 | PHP_HASH_API void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input, |
334 | unsigned int inputLen) |
335 | { |
336 | unsigned int i, index, partLen; |
337 | |
338 | /* Compute number of bytes mod 64 */ |
339 | index = (unsigned int) ((context->count[0] >> 3) & 0x3F); |
340 | |
341 | /* Update number of bits */ |
342 | if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) |
343 | < ((php_hash_uint32) inputLen << 3)) |
344 | context->count[1]++; |
345 | context->count[1] += ((php_hash_uint32) inputLen >> 29); |
346 | |
347 | partLen = 64 - index; |
348 | |
349 | /* Transform as many times as possible. |
350 | */ |
351 | if (inputLen >= partLen) { |
352 | memcpy |
353 | ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); |
354 | SHA1Transform(context->state, context->buffer); |
355 | |
356 | for (i = partLen; i + 63 < inputLen; i += 64) |
357 | SHA1Transform(context->state, &input[i]); |
358 | |
359 | index = 0; |
360 | } else |
361 | i = 0; |
362 | |
363 | /* Buffer remaining input */ |
364 | memcpy |
365 | ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], |
366 | inputLen - i); |
367 | } |
368 | /* }}} */ |
369 | |
370 | /* {{{ PHP_SHA1Final |
371 | SHA1 finalization. Ends an SHA1 message-digest operation, writing the |
372 | the message digest and zeroizing the context. |
373 | */ |
374 | PHP_HASH_API void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context) |
375 | { |
376 | unsigned char bits[8]; |
377 | unsigned int index, padLen; |
378 | |
379 | /* Save number of bits */ |
380 | bits[7] = context->count[0] & 0xFF; |
381 | bits[6] = (context->count[0] >> 8) & 0xFF; |
382 | bits[5] = (context->count[0] >> 16) & 0xFF; |
383 | bits[4] = (context->count[0] >> 24) & 0xFF; |
384 | bits[3] = context->count[1] & 0xFF; |
385 | bits[2] = (context->count[1] >> 8) & 0xFF; |
386 | bits[1] = (context->count[1] >> 16) & 0xFF; |
387 | bits[0] = (context->count[1] >> 24) & 0xFF; |
388 | |
389 | /* Pad out to 56 mod 64. |
390 | */ |
391 | index = (unsigned int) ((context->count[0] >> 3) & 0x3f); |
392 | padLen = (index < 56) ? (56 - index) : (120 - index); |
393 | PHP_SHA1Update(context, PADDING, padLen); |
394 | |
395 | /* Append length (before padding) */ |
396 | PHP_SHA1Update(context, bits, 8); |
397 | |
398 | /* Store state in digest */ |
399 | SHAEncode32(digest, context->state, 20); |
400 | |
401 | /* Zeroize sensitive information. |
402 | */ |
403 | memset((unsigned char*) context, 0, sizeof(*context)); |
404 | } |
405 | /* }}} */ |
406 | |
407 | #endif /* PHP_HASH_SHA1_NOT_IN_CORE */ |
408 | |
409 | /* sha224/sha256 */ |
410 | |
411 | const php_hash_ops php_hash_sha256_ops = { |
412 | (php_hash_init_func_t) PHP_SHA256Init, |
413 | (php_hash_update_func_t) PHP_SHA256Update, |
414 | (php_hash_final_func_t) PHP_SHA256Final, |
415 | (php_hash_copy_func_t) php_hash_copy, |
416 | 32, |
417 | 64, |
418 | sizeof(PHP_SHA256_CTX) |
419 | }; |
420 | |
421 | const php_hash_ops php_hash_sha224_ops = { |
422 | (php_hash_init_func_t) PHP_SHA224Init, |
423 | (php_hash_update_func_t) PHP_SHA224Update, |
424 | (php_hash_final_func_t) PHP_SHA224Final, |
425 | (php_hash_copy_func_t) php_hash_copy, |
426 | 28, |
427 | 64, |
428 | sizeof(PHP_SHA224_CTX) |
429 | }; |
430 | |
431 | #define ROTR32(b,x) ((x >> b) | (x << (32 - b))) |
432 | #define ROTR64(b,x) ((x >> b) | (x << (64 - b))) |
433 | #define SHR(b, x) (x >> b) |
434 | |
435 | /* Ch */ |
436 | #define SHA256_F0(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) |
437 | /* Maj */ |
438 | #define SHA256_F1(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) |
439 | /* SUM0 */ |
440 | #define SHA256_F2(x) (ROTR32( 2,(x)) ^ ROTR32(13,(x)) ^ ROTR32(22,(x))) |
441 | /* SUM1 */ |
442 | #define SHA256_F3(x) (ROTR32( 6,(x)) ^ ROTR32(11,(x)) ^ ROTR32(25,(x))) |
443 | /* OM0 */ |
444 | #define SHA256_F4(x) (ROTR32( 7,(x)) ^ ROTR32(18,(x)) ^ SHR( 3,(x))) |
445 | /* OM1 */ |
446 | #define SHA256_F5(x) (ROTR32(17,(x)) ^ ROTR32(19,(x)) ^ SHR(10,(x))) |
447 | |
448 | static const php_hash_uint32 SHA256_K[64] = { |
449 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, |
450 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, |
451 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
452 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, |
453 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, |
454 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
455 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, |
456 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; |
457 | |
458 | /* {{{ PHP_SHA256Init |
459 | * SHA256 initialization. Begins an SHA256 operation, writing a new context. |
460 | */ |
461 | PHP_HASH_API void PHP_SHA256Init(PHP_SHA256_CTX * context) |
462 | { |
463 | context->count[0] = context->count[1] = 0; |
464 | /* Load magic initialization constants. |
465 | */ |
466 | context->state[0] = 0x6a09e667; |
467 | context->state[1] = 0xbb67ae85; |
468 | context->state[2] = 0x3c6ef372; |
469 | context->state[3] = 0xa54ff53a; |
470 | context->state[4] = 0x510e527f; |
471 | context->state[5] = 0x9b05688c; |
472 | context->state[6] = 0x1f83d9ab; |
473 | context->state[7] = 0x5be0cd19; |
474 | } |
475 | /* }}} */ |
476 | |
477 | /* {{{ SHA256Transform |
478 | * SHA256 basic transformation. Transforms state based on block. |
479 | */ |
480 | static void SHA256Transform(php_hash_uint32 state[8], const unsigned char block[64]) |
481 | { |
482 | php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3]; |
483 | php_hash_uint32 e = state[4], f = state[5], g = state[6], h = state[7]; |
484 | php_hash_uint32 x[16], T1, T2, W[64]; |
485 | int i; |
486 | |
487 | SHADecode32(x, block, 64); |
488 | |
489 | /* Schedule */ |
490 | for(i = 0; i < 16; i++) { |
491 | W[i] = x[i]; |
492 | } |
493 | for(i = 16; i < 64; i++) { |
494 | W[i] = SHA256_F5(W[i-2]) + W[i-7] + SHA256_F4(W[i-15]) + W[i-16]; |
495 | } |
496 | |
497 | for (i = 0; i < 64; i++) { |
498 | T1 = h + SHA256_F3(e) + SHA256_F0(e,f,g) + SHA256_K[i] + W[i]; |
499 | T2 = SHA256_F2(a) + SHA256_F1(a,b,c); |
500 | h = g; g = f; f = e; e = d + T1; |
501 | d = c; c = b; b = a; a = T1 + T2; |
502 | } |
503 | |
504 | state[0] += a; |
505 | state[1] += b; |
506 | state[2] += c; |
507 | state[3] += d; |
508 | state[4] += e; |
509 | state[5] += f; |
510 | state[6] += g; |
511 | state[7] += h; |
512 | |
513 | /* Zeroize sensitive information. */ |
514 | memset((unsigned char*) x, 0, sizeof(x)); |
515 | } |
516 | /* }}} */ |
517 | |
518 | /* {{{ PHP_SHA224Init |
519 | * SHA224 initialization. Begins an SHA224 operation, writing a new context. |
520 | */ |
521 | PHP_HASH_API void PHP_SHA224Init(PHP_SHA224_CTX * context) |
522 | { |
523 | context->count[0] = context->count[1] = 0; |
524 | /* Load magic initialization constants. |
525 | */ |
526 | context->state[0] = 0xc1059ed8; |
527 | context->state[1] = 0x367cd507; |
528 | context->state[2] = 0x3070dd17; |
529 | context->state[3] = 0xf70e5939; |
530 | context->state[4] = 0xffc00b31; |
531 | context->state[5] = 0x68581511; |
532 | context->state[6] = 0x64f98fa7; |
533 | context->state[7] = 0xbefa4fa4; |
534 | } |
535 | /* }}} */ |
536 | |
537 | /* {{{ PHP_SHA224Update |
538 | SHA224 block update operation. Continues an SHA224 message-digest |
539 | operation, processing another message block, and updating the |
540 | context. |
541 | */ |
542 | PHP_HASH_API void PHP_SHA224Update(PHP_SHA224_CTX * context, const unsigned char *input, unsigned int inputLen) |
543 | { |
544 | unsigned int i, index, partLen; |
545 | |
546 | /* Compute number of bytes mod 64 */ |
547 | index = (unsigned int) ((context->count[0] >> 3) & 0x3F); |
548 | |
549 | /* Update number of bits */ |
550 | if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) { |
551 | context->count[1]++; |
552 | } |
553 | context->count[1] += ((php_hash_uint32) inputLen >> 29); |
554 | |
555 | partLen = 64 - index; |
556 | |
557 | /* Transform as many times as possible. |
558 | */ |
559 | if (inputLen >= partLen) { |
560 | memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); |
561 | SHA256Transform(context->state, context->buffer); |
562 | |
563 | for (i = partLen; i + 63 < inputLen; i += 64) { |
564 | SHA256Transform(context->state, &input[i]); |
565 | } |
566 | |
567 | index = 0; |
568 | } else { |
569 | i = 0; |
570 | } |
571 | |
572 | /* Buffer remaining input */ |
573 | memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i); |
574 | } |
575 | /* }}} */ |
576 | |
577 | /* {{{ PHP_SHA224Final |
578 | SHA224 finalization. Ends an SHA224 message-digest operation, writing the |
579 | the message digest and zeroizing the context. |
580 | */ |
581 | PHP_HASH_API void PHP_SHA224Final(unsigned char digest[28], PHP_SHA224_CTX * context) |
582 | { |
583 | unsigned char bits[8]; |
584 | unsigned int index, padLen; |
585 | |
586 | /* Save number of bits */ |
587 | bits[7] = (unsigned char) (context->count[0] & 0xFF); |
588 | bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF); |
589 | bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF); |
590 | bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF); |
591 | bits[3] = (unsigned char) (context->count[1] & 0xFF); |
592 | bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF); |
593 | bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF); |
594 | bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF); |
595 | |
596 | /* Pad out to 56 mod 64. |
597 | */ |
598 | index = (unsigned int) ((context->count[0] >> 3) & 0x3f); |
599 | padLen = (index < 56) ? (56 - index) : (120 - index); |
600 | PHP_SHA224Update(context, PADDING, padLen); |
601 | |
602 | /* Append length (before padding) */ |
603 | PHP_SHA224Update(context, bits, 8); |
604 | |
605 | /* Store state in digest */ |
606 | SHAEncode32(digest, context->state, 28); |
607 | |
608 | /* Zeroize sensitive information. |
609 | */ |
610 | memset((unsigned char*) context, 0, sizeof(*context)); |
611 | } |
612 | /* }}} */ |
613 | |
614 | /* {{{ PHP_SHA256Update |
615 | SHA256 block update operation. Continues an SHA256 message-digest |
616 | operation, processing another message block, and updating the |
617 | context. |
618 | */ |
619 | PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, unsigned int inputLen) |
620 | { |
621 | unsigned int i, index, partLen; |
622 | |
623 | /* Compute number of bytes mod 64 */ |
624 | index = (unsigned int) ((context->count[0] >> 3) & 0x3F); |
625 | |
626 | /* Update number of bits */ |
627 | if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) { |
628 | context->count[1]++; |
629 | } |
630 | context->count[1] += ((php_hash_uint32) inputLen >> 29); |
631 | |
632 | partLen = 64 - index; |
633 | |
634 | /* Transform as many times as possible. |
635 | */ |
636 | if (inputLen >= partLen) { |
637 | memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); |
638 | SHA256Transform(context->state, context->buffer); |
639 | |
640 | for (i = partLen; i + 63 < inputLen; i += 64) { |
641 | SHA256Transform(context->state, &input[i]); |
642 | } |
643 | |
644 | index = 0; |
645 | } else { |
646 | i = 0; |
647 | } |
648 | |
649 | /* Buffer remaining input */ |
650 | memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i); |
651 | } |
652 | /* }}} */ |
653 | |
654 | /* {{{ PHP_SHA256Final |
655 | SHA256 finalization. Ends an SHA256 message-digest operation, writing the |
656 | the message digest and zeroizing the context. |
657 | */ |
658 | PHP_HASH_API void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) |
659 | { |
660 | unsigned char bits[8]; |
661 | unsigned int index, padLen; |
662 | |
663 | /* Save number of bits */ |
664 | bits[7] = (unsigned char) (context->count[0] & 0xFF); |
665 | bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF); |
666 | bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF); |
667 | bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF); |
668 | bits[3] = (unsigned char) (context->count[1] & 0xFF); |
669 | bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF); |
670 | bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF); |
671 | bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF); |
672 | |
673 | /* Pad out to 56 mod 64. |
674 | */ |
675 | index = (unsigned int) ((context->count[0] >> 3) & 0x3f); |
676 | padLen = (index < 56) ? (56 - index) : (120 - index); |
677 | PHP_SHA256Update(context, PADDING, padLen); |
678 | |
679 | /* Append length (before padding) */ |
680 | PHP_SHA256Update(context, bits, 8); |
681 | |
682 | /* Store state in digest */ |
683 | SHAEncode32(digest, context->state, 32); |
684 | |
685 | /* Zeroize sensitive information. |
686 | */ |
687 | memset((unsigned char*) context, 0, sizeof(*context)); |
688 | } |
689 | /* }}} */ |
690 | |
691 | /* sha384/sha512 */ |
692 | |
693 | /* Ch */ |
694 | #define SHA512_F0(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) |
695 | /* Maj */ |
696 | #define SHA512_F1(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) |
697 | /* SUM0 */ |
698 | #define SHA512_F2(x) (ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x)) |
699 | /* SUM1 */ |
700 | #define SHA512_F3(x) (ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x)) |
701 | /* OM0 */ |
702 | #define SHA512_F4(x) (ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR(7, x)) |
703 | /* OM1 */ |
704 | #define SHA512_F5(x) (ROTR64(19, x) ^ ROTR64(61, x) ^ SHR(6, x)) |
705 | |
706 | static const php_hash_uint64 SHA512_K[128] = { |
707 | L64(0x428a2f98d728ae22), L64(0x7137449123ef65cd), L64(0xb5c0fbcfec4d3b2f), L64(0xe9b5dba58189dbbc), |
708 | L64(0x3956c25bf348b538), L64(0x59f111f1b605d019), L64(0x923f82a4af194f9b), L64(0xab1c5ed5da6d8118), |
709 | L64(0xd807aa98a3030242), L64(0x12835b0145706fbe), L64(0x243185be4ee4b28c), L64(0x550c7dc3d5ffb4e2), |
710 | L64(0x72be5d74f27b896f), L64(0x80deb1fe3b1696b1), L64(0x9bdc06a725c71235), L64(0xc19bf174cf692694), |
711 | L64(0xe49b69c19ef14ad2), L64(0xefbe4786384f25e3), L64(0x0fc19dc68b8cd5b5), L64(0x240ca1cc77ac9c65), |
712 | L64(0x2de92c6f592b0275), L64(0x4a7484aa6ea6e483), L64(0x5cb0a9dcbd41fbd4), L64(0x76f988da831153b5), |
713 | L64(0x983e5152ee66dfab), L64(0xa831c66d2db43210), L64(0xb00327c898fb213f), L64(0xbf597fc7beef0ee4), |
714 | L64(0xc6e00bf33da88fc2), L64(0xd5a79147930aa725), L64(0x06ca6351e003826f), L64(0x142929670a0e6e70), |
715 | L64(0x27b70a8546d22ffc), L64(0x2e1b21385c26c926), L64(0x4d2c6dfc5ac42aed), L64(0x53380d139d95b3df), |
716 | L64(0x650a73548baf63de), L64(0x766a0abb3c77b2a8), L64(0x81c2c92e47edaee6), L64(0x92722c851482353b), |
717 | L64(0xa2bfe8a14cf10364), L64(0xa81a664bbc423001), L64(0xc24b8b70d0f89791), L64(0xc76c51a30654be30), |
718 | L64(0xd192e819d6ef5218), L64(0xd69906245565a910), L64(0xf40e35855771202a), L64(0x106aa07032bbd1b8), |
719 | L64(0x19a4c116b8d2d0c8), L64(0x1e376c085141ab53), L64(0x2748774cdf8eeb99), L64(0x34b0bcb5e19b48a8), |
720 | L64(0x391c0cb3c5c95a63), L64(0x4ed8aa4ae3418acb), L64(0x5b9cca4f7763e373), L64(0x682e6ff3d6b2b8a3), |
721 | L64(0x748f82ee5defb2fc), L64(0x78a5636f43172f60), L64(0x84c87814a1f0ab72), L64(0x8cc702081a6439ec), |
722 | L64(0x90befffa23631e28), L64(0xa4506cebde82bde9), L64(0xbef9a3f7b2c67915), L64(0xc67178f2e372532b), |
723 | L64(0xca273eceea26619c), L64(0xd186b8c721c0c207), L64(0xeada7dd6cde0eb1e), L64(0xf57d4f7fee6ed178), |
724 | L64(0x06f067aa72176fba), L64(0x0a637dc5a2c898a6), L64(0x113f9804bef90dae), L64(0x1b710b35131c471b), |
725 | L64(0x28db77f523047d84), L64(0x32caab7b40c72493), L64(0x3c9ebe0a15c9bebc), L64(0x431d67c49c100d4c), |
726 | L64(0x4cc5d4becb3e42b6), L64(0x597f299cfc657e2a), L64(0x5fcb6fab3ad6faec), L64(0x6c44198c4a475817) }; |
727 | |
728 | /* {{{ SHAEncode64 |
729 | Encodes input (php_hash_uint64) into output (unsigned char). Assumes len is |
730 | a multiple of 8. |
731 | */ |
732 | static void SHAEncode64(unsigned char *output, php_hash_uint64 *input, unsigned int len) |
733 | { |
734 | unsigned int i, j; |
735 | |
736 | for (i = 0, j = 0; j < len; i++, j += 8) { |
737 | output[j] = (unsigned char) ((input[i] >> 56) & 0xff); |
738 | output[j + 1] = (unsigned char) ((input[i] >> 48) & 0xff); |
739 | output[j + 2] = (unsigned char) ((input[i] >> 40) & 0xff); |
740 | output[j + 3] = (unsigned char) ((input[i] >> 32) & 0xff); |
741 | output[j + 4] = (unsigned char) ((input[i] >> 24) & 0xff); |
742 | output[j + 5] = (unsigned char) ((input[i] >> 16) & 0xff); |
743 | output[j + 6] = (unsigned char) ((input[i] >> 8) & 0xff); |
744 | output[j + 7] = (unsigned char) (input[i] & 0xff); |
745 | } |
746 | } |
747 | /* }}} */ |
748 | |
749 | |
750 | /* {{{ SHADecode64 |
751 | Decodes input (unsigned char) into output (php_hash_uint64). Assumes len is |
752 | a multiple of 8. |
753 | */ |
754 | static void SHADecode64(php_hash_uint64 *output, const unsigned char *input, unsigned int len) |
755 | { |
756 | unsigned int i, j; |
757 | |
758 | for (i = 0, j = 0; j < len; i++, j += 8) |
759 | output[i] = |
760 | ((php_hash_uint64) input[j + 7]) | (((php_hash_uint64) input[j + 6]) << 8) | |
761 | (((php_hash_uint64) input[j + 5]) << 16) | (((php_hash_uint64) input[j + 4]) << 24) | |
762 | (((php_hash_uint64) input[j + 3]) << 32) | (((php_hash_uint64) input[j + 2]) << 40) | |
763 | (((php_hash_uint64) input[j + 1]) << 48) | (((php_hash_uint64) input[j]) << 56); |
764 | } |
765 | /* }}} */ |
766 | |
767 | /* {{{ PHP_SHA384Init |
768 | * SHA384 initialization. Begins an SHA384 operation, writing a new context. |
769 | */ |
770 | PHP_HASH_API void PHP_SHA384Init(PHP_SHA384_CTX * context) |
771 | { |
772 | context->count[0] = context->count[1] = 0; |
773 | /* Load magic initialization constants. |
774 | */ |
775 | context->state[0] = L64(0xcbbb9d5dc1059ed8); |
776 | context->state[1] = L64(0x629a292a367cd507); |
777 | context->state[2] = L64(0x9159015a3070dd17); |
778 | context->state[3] = L64(0x152fecd8f70e5939); |
779 | context->state[4] = L64(0x67332667ffc00b31); |
780 | context->state[5] = L64(0x8eb44a8768581511); |
781 | context->state[6] = L64(0xdb0c2e0d64f98fa7); |
782 | context->state[7] = L64(0x47b5481dbefa4fa4); |
783 | } |
784 | /* }}} */ |
785 | |
786 | /* {{{ SHA512Transform |
787 | * SHA512 basic transformation. Transforms state based on block. |
788 | * SHA384 uses the exact same algorithm |
789 | */ |
790 | static void SHA512Transform(php_hash_uint64 state[8], const unsigned char block[128]) |
791 | { |
792 | php_hash_uint64 a = state[0], b = state[1], c = state[2], d = state[3]; |
793 | php_hash_uint64 e = state[4], f = state[5], g = state[6], h = state[7]; |
794 | php_hash_uint64 x[16], T1, T2, W[80]; |
795 | int i; |
796 | |
797 | SHADecode64(x, block, 128); |
798 | |
799 | /* Schedule */ |
800 | for(i = 0; i < 16; i++) { |
801 | W[i] = x[i]; |
802 | } |
803 | for(i = 16; i < 80; i++) { |
804 | W[i] = SHA512_F5(W[i-2]) + W[i-7] + SHA512_F4(W[i-15]) + W[i-16]; |
805 | } |
806 | |
807 | for (i = 0; i < 80; i++) { |
808 | T1 = h + SHA512_F3(e) + SHA512_F0(e,f,g) + SHA512_K[i] + W[i]; |
809 | T2 = SHA512_F2(a) + SHA512_F1(a,b,c); |
810 | h = g; g = f; f = e; e = d + T1; |
811 | d = c; c = b; b = a; a = T1 + T2; |
812 | } |
813 | |
814 | state[0] += a; |
815 | state[1] += b; |
816 | state[2] += c; |
817 | state[3] += d; |
818 | state[4] += e; |
819 | state[5] += f; |
820 | state[6] += g; |
821 | state[7] += h; |
822 | |
823 | /* Zeroize sensitive information. */ |
824 | memset((unsigned char*) x, 0, sizeof(x)); |
825 | } |
826 | /* }}} */ |
827 | |
828 | /* {{{ PHP_SHA384Update |
829 | SHA384 block update operation. Continues an SHA384 message-digest |
830 | operation, processing another message block, and updating the |
831 | context. |
832 | */ |
833 | PHP_HASH_API void PHP_SHA384Update(PHP_SHA384_CTX * context, const unsigned char *input, unsigned int inputLen) |
834 | { |
835 | unsigned int i, index, partLen; |
836 | |
837 | /* Compute number of bytes mod 128 */ |
838 | index = (unsigned int) ((context->count[0] >> 3) & 0x7F); |
839 | |
840 | /* Update number of bits */ |
841 | if ((context->count[0] += ((php_hash_uint64) inputLen << 3)) < ((php_hash_uint64) inputLen << 3)) { |
842 | context->count[1]++; |
843 | } |
844 | context->count[1] += ((php_hash_uint64) inputLen >> 61); |
845 | |
846 | partLen = 128 - index; |
847 | |
848 | /* Transform as many times as possible. |
849 | */ |
850 | if (inputLen >= partLen) { |
851 | memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); |
852 | SHA512Transform(context->state, context->buffer); |
853 | |
854 | for (i = partLen; i + 127 < inputLen; i += 128) { |
855 | SHA512Transform(context->state, &input[i]); |
856 | } |
857 | |
858 | index = 0; |
859 | } else { |
860 | i = 0; |
861 | } |
862 | |
863 | /* Buffer remaining input */ |
864 | memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i); |
865 | } |
866 | /* }}} */ |
867 | |
868 | /* {{{ PHP_SHA384Final |
869 | SHA384 finalization. Ends an SHA384 message-digest operation, writing the |
870 | the message digest and zeroizing the context. |
871 | */ |
872 | PHP_HASH_API void PHP_SHA384Final(unsigned char digest[48], PHP_SHA384_CTX * context) |
873 | { |
874 | unsigned char bits[16]; |
875 | unsigned int index, padLen; |
876 | |
877 | /* Save number of bits */ |
878 | bits[15] = (unsigned char) (context->count[0] & 0xFF); |
879 | bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF); |
880 | bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF); |
881 | bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF); |
882 | bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF); |
883 | bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF); |
884 | bits[9] = (unsigned char) ((context->count[0] >> 48) & 0xFF); |
885 | bits[8] = (unsigned char) ((context->count[0] >> 56) & 0xFF); |
886 | bits[7] = (unsigned char) (context->count[1] & 0xFF); |
887 | bits[6] = (unsigned char) ((context->count[1] >> 8) & 0xFF); |
888 | bits[5] = (unsigned char) ((context->count[1] >> 16) & 0xFF); |
889 | bits[4] = (unsigned char) ((context->count[1] >> 24) & 0xFF); |
890 | bits[3] = (unsigned char) ((context->count[1] >> 32) & 0xFF); |
891 | bits[2] = (unsigned char) ((context->count[1] >> 40) & 0xFF); |
892 | bits[1] = (unsigned char) ((context->count[1] >> 48) & 0xFF); |
893 | bits[0] = (unsigned char) ((context->count[1] >> 56) & 0xFF); |
894 | |
895 | /* Pad out to 112 mod 128. |
896 | */ |
897 | index = (unsigned int) ((context->count[0] >> 3) & 0x7f); |
898 | padLen = (index < 112) ? (112 - index) : (240 - index); |
899 | PHP_SHA384Update(context, PADDING, padLen); |
900 | |
901 | /* Append length (before padding) */ |
902 | PHP_SHA384Update(context, bits, 16); |
903 | |
904 | /* Store state in digest */ |
905 | SHAEncode64(digest, context->state, 48); |
906 | |
907 | /* Zeroize sensitive information. |
908 | */ |
909 | memset((unsigned char*) context, 0, sizeof(*context)); |
910 | } |
911 | /* }}} */ |
912 | |
913 | const php_hash_ops php_hash_sha384_ops = { |
914 | (php_hash_init_func_t) PHP_SHA384Init, |
915 | (php_hash_update_func_t) PHP_SHA384Update, |
916 | (php_hash_final_func_t) PHP_SHA384Final, |
917 | (php_hash_copy_func_t) php_hash_copy, |
918 | 48, |
919 | 128, |
920 | sizeof(PHP_SHA384_CTX) |
921 | }; |
922 | |
923 | /* {{{ PHP_SHA512Init |
924 | * SHA512 initialization. Begins an SHA512 operation, writing a new context. |
925 | */ |
926 | PHP_HASH_API void PHP_SHA512Init(PHP_SHA512_CTX * context) |
927 | { |
928 | context->count[0] = context->count[1] = 0; |
929 | /* Load magic initialization constants. |
930 | */ |
931 | context->state[0] = L64(0x6a09e667f3bcc908); |
932 | context->state[1] = L64(0xbb67ae8584caa73b); |
933 | context->state[2] = L64(0x3c6ef372fe94f82b); |
934 | context->state[3] = L64(0xa54ff53a5f1d36f1); |
935 | context->state[4] = L64(0x510e527fade682d1); |
936 | context->state[5] = L64(0x9b05688c2b3e6c1f); |
937 | context->state[6] = L64(0x1f83d9abfb41bd6b); |
938 | context->state[7] = L64(0x5be0cd19137e2179); |
939 | } |
940 | /* }}} */ |
941 | |
942 | /* {{{ PHP_SHA512Update |
943 | SHA512 block update operation. Continues an SHA512 message-digest |
944 | operation, processing another message block, and updating the |
945 | context. |
946 | */ |
947 | PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX * context, const unsigned char *input, unsigned int inputLen) |
948 | { |
949 | unsigned int i, index, partLen; |
950 | |
951 | /* Compute number of bytes mod 128 */ |
952 | index = (unsigned int) ((context->count[0] >> 3) & 0x7F); |
953 | |
954 | /* Update number of bits */ |
955 | if ((context->count[0] += ((php_hash_uint64) inputLen << 3)) < ((php_hash_uint64) inputLen << 3)) { |
956 | context->count[1]++; |
957 | } |
958 | context->count[1] += ((php_hash_uint64) inputLen >> 61); |
959 | |
960 | partLen = 128 - index; |
961 | |
962 | /* Transform as many times as possible. |
963 | */ |
964 | if (inputLen >= partLen) { |
965 | memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); |
966 | SHA512Transform(context->state, context->buffer); |
967 | |
968 | for (i = partLen; i + 127 < inputLen; i += 128) { |
969 | SHA512Transform(context->state, &input[i]); |
970 | } |
971 | |
972 | index = 0; |
973 | } else { |
974 | i = 0; |
975 | } |
976 | |
977 | /* Buffer remaining input */ |
978 | memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i); |
979 | } |
980 | /* }}} */ |
981 | |
982 | /* {{{ PHP_SHA512Final |
983 | SHA512 finalization. Ends an SHA512 message-digest operation, writing the |
984 | the message digest and zeroizing the context. |
985 | */ |
986 | PHP_HASH_API void PHP_SHA512Final(unsigned char digest[64], PHP_SHA512_CTX * context) |
987 | { |
988 | unsigned char bits[16]; |
989 | unsigned int index, padLen; |
990 | |
991 | /* Save number of bits */ |
992 | bits[15] = (unsigned char) (context->count[0] & 0xFF); |
993 | bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF); |
994 | bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF); |
995 | bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF); |
996 | bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF); |
997 | bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF); |
998 | bits[9] = (unsigned char) ((context->count[0] >> 48) & 0xFF); |
999 | bits[8] = (unsigned char) ((context->count[0] >> 56) & 0xFF); |
1000 | bits[7] = (unsigned char) (context->count[1] & 0xFF); |
1001 | bits[6] = (unsigned char) ((context->count[1] >> 8) & 0xFF); |
1002 | bits[5] = (unsigned char) ((context->count[1] >> 16) & 0xFF); |
1003 | bits[4] = (unsigned char) ((context->count[1] >> 24) & 0xFF); |
1004 | bits[3] = (unsigned char) ((context->count[1] >> 32) & 0xFF); |
1005 | bits[2] = (unsigned char) ((context->count[1] >> 40) & 0xFF); |
1006 | bits[1] = (unsigned char) ((context->count[1] >> 48) & 0xFF); |
1007 | bits[0] = (unsigned char) ((context->count[1] >> 56) & 0xFF); |
1008 | |
1009 | /* Pad out to 112 mod 128. |
1010 | */ |
1011 | index = (unsigned int) ((context->count[0] >> 3) & 0x7f); |
1012 | padLen = (index < 112) ? (112 - index) : (240 - index); |
1013 | PHP_SHA512Update(context, PADDING, padLen); |
1014 | |
1015 | /* Append length (before padding) */ |
1016 | PHP_SHA512Update(context, bits, 16); |
1017 | |
1018 | /* Store state in digest */ |
1019 | SHAEncode64(digest, context->state, 64); |
1020 | |
1021 | /* Zeroize sensitive information. |
1022 | */ |
1023 | memset((unsigned char*) context, 0, sizeof(*context)); |
1024 | } |
1025 | /* }}} */ |
1026 | |
1027 | const php_hash_ops php_hash_sha512_ops = { |
1028 | (php_hash_init_func_t) PHP_SHA512Init, |
1029 | (php_hash_update_func_t) PHP_SHA512Update, |
1030 | (php_hash_final_func_t) PHP_SHA512Final, |
1031 | (php_hash_copy_func_t) php_hash_copy, |
1032 | 64, |
1033 | 128, |
1034 | sizeof(PHP_SHA512_CTX) |
1035 | }; |
1036 | |
1037 | /* |
1038 | * Local variables: |
1039 | * tab-width: 4 |
1040 | * c-basic-offset: 4 |
1041 | * End: |
1042 | * vim600: sw=4 ts=4 fdm=marker |
1043 | * vim<600: sw=4 ts=4 |
1044 | */ |
1045 | |