1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 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 | Author: Sara Golemon <pollita@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* Heavily borrowed from md5.c & sha1.c of PHP archival fame
20 Note that ripemd laughs in the face of logic and uses
21 little endian byte ordering */
22
23 #include "php_hash.h"
24 #include "php_hash_ripemd.h"
25
26 const php_hash_ops php_hash_ripemd128_ops = {
27 (php_hash_init_func_t) PHP_RIPEMD128Init,
28 (php_hash_update_func_t) PHP_RIPEMD128Update,
29 (php_hash_final_func_t) PHP_RIPEMD128Final,
30 (php_hash_copy_func_t) php_hash_copy,
31 16,
32 64,
33 sizeof(PHP_RIPEMD128_CTX),
34 1
35 };
36
37 const php_hash_ops php_hash_ripemd160_ops = {
38 (php_hash_init_func_t) PHP_RIPEMD160Init,
39 (php_hash_update_func_t) PHP_RIPEMD160Update,
40 (php_hash_final_func_t) PHP_RIPEMD160Final,
41 (php_hash_copy_func_t) php_hash_copy,
42 20,
43 64,
44 sizeof(PHP_RIPEMD160_CTX),
45 1
46 };
47
48 const php_hash_ops php_hash_ripemd256_ops = {
49 (php_hash_init_func_t) PHP_RIPEMD256Init,
50 (php_hash_update_func_t) PHP_RIPEMD256Update,
51 (php_hash_final_func_t) PHP_RIPEMD256Final,
52 (php_hash_copy_func_t) php_hash_copy,
53 32,
54 64,
55 sizeof(PHP_RIPEMD256_CTX),
56 1
57 };
58
59 const php_hash_ops php_hash_ripemd320_ops = {
60 (php_hash_init_func_t) PHP_RIPEMD320Init,
61 (php_hash_update_func_t) PHP_RIPEMD320Update,
62 (php_hash_final_func_t) PHP_RIPEMD320Final,
63 (php_hash_copy_func_t) php_hash_copy,
64 40,
65 64,
66 sizeof(PHP_RIPEMD320_CTX),
67 1
68 };
69
70 /* {{{ PHP_RIPEMD128Init
71 * ripemd128 initialization. Begins a ripemd128 operation, writing a new context.
72 */
PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context)73 PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context)
74 {
75 context->count[0] = context->count[1] = 0;
76 /* Load magic initialization constants.
77 */
78 context->state[0] = 0x67452301;
79 context->state[1] = 0xEFCDAB89;
80 context->state[2] = 0x98BADCFE;
81 context->state[3] = 0x10325476;
82 }
83 /* }}} */
84
85 /* {{{ PHP_RIPEMD256Init
86 * ripemd256 initialization. Begins a ripemd256 operation, writing a new context.
87 */
PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context)88 PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context)
89 {
90 context->count[0] = context->count[1] = 0;
91 /* Load magic initialization constants.
92 */
93 context->state[0] = 0x67452301;
94 context->state[1] = 0xEFCDAB89;
95 context->state[2] = 0x98BADCFE;
96 context->state[3] = 0x10325476;
97 context->state[4] = 0x76543210;
98 context->state[5] = 0xFEDCBA98;
99 context->state[6] = 0x89ABCDEF;
100 context->state[7] = 0x01234567;
101 }
102 /* }}} */
103
104 /* {{{ PHP_RIPEMD160Init
105 * ripemd160 initialization. Begins a ripemd160 operation, writing a new context.
106 */
PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context)107 PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context)
108 {
109 context->count[0] = context->count[1] = 0;
110 /* Load magic initialization constants.
111 */
112 context->state[0] = 0x67452301;
113 context->state[1] = 0xEFCDAB89;
114 context->state[2] = 0x98BADCFE;
115 context->state[3] = 0x10325476;
116 context->state[4] = 0xC3D2E1F0;
117 }
118 /* }}} */
119
120 /* {{{ PHP_RIPEMD320Init
121 * ripemd320 initialization. Begins a ripemd320 operation, writing a new context.
122 */
PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context)123 PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context)
124 {
125 context->count[0] = context->count[1] = 0;
126 /* Load magic initialization constants.
127 */
128 context->state[0] = 0x67452301;
129 context->state[1] = 0xEFCDAB89;
130 context->state[2] = 0x98BADCFE;
131 context->state[3] = 0x10325476;
132 context->state[4] = 0xC3D2E1F0;
133 context->state[5] = 0x76543210;
134 context->state[6] = 0xFEDCBA98;
135 context->state[7] = 0x89ABCDEF;
136 context->state[8] = 0x01234567;
137 context->state[9] = 0x3C2D1E0F;
138 }
139 /* }}} */
140
141 /* Basic ripemd function */
142 #define F0(x,y,z) ((x) ^ (y) ^ (z))
143 #define F1(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
144 #define F2(x,y,z) (((x) | (~(y))) ^ (z))
145 #define F3(x,y,z) (((x) & (z)) | ((y) & (~(z))))
146 #define F4(x,y,z) ((x) ^ ((y) | (~(z))))
147
148 static const uint32_t K_values[5] = { 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E }; /* 128, 256, 160, 320 */
149 static const uint32_t KK_values[4] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x00000000 }; /* 128 & 256 */
150 static const uint32_t KK160_values[5] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000 }; /* 160 & 320 */
151
152 #define K(n) K_values[ (n) >> 4]
153 #define KK(n) KK_values[(n) >> 4]
154 #define KK160(n) KK160_values[(n) >> 4]
155
156 static const unsigned char R[80] = {
157 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
158 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
159 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
160 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
161 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 };
162
163 static const unsigned char RR[80] = {
164 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
165 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
166 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
167 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
168 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 };
169
170 static const unsigned char S[80] = {
171 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
172 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
173 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
174 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
175 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 };
176
177 static const unsigned char SS[80] = {
178 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
179 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
180 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
181 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
182 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
183
184 #define ROLS(j, x) (((x) << S[j]) | ((x) >> (32 - S[j])))
185 #define ROLSS(j, x) (((x) << SS[j]) | ((x) >> (32 - SS[j])))
186 #define ROL(n, x) (((x) << n) | ((x) >> (32 - n)))
187
188 /* {{{ RIPEMDDecode
189 Decodes input (unsigned char) into output (uint32_t). Assumes len is
190 a multiple of 4.
191 */
RIPEMDDecode(uint32_t * output,const unsigned char * input,unsigned int len)192 static void RIPEMDDecode(uint32_t *output, const unsigned char *input, unsigned int len)
193 {
194 unsigned int i, j;
195
196 for (i = 0, j = 0; j < len; i++, j += 4)
197 output[i] = ((uint32_t) input[j + 0]) | (((uint32_t) input[j + 1]) << 8) |
198 (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24);
199 }
200 /* }}} */
201
202 /* {{{ RIPEMD128Transform
203 * ripemd128 basic transformation. Transforms state based on block.
204 */
RIPEMD128Transform(uint32_t state[4],const unsigned char block[64])205 static void RIPEMD128Transform(uint32_t state[4], const unsigned char block[64])
206 {
207 uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
208 uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3];
209 uint32_t tmp, x[16];
210 int j;
211
212 RIPEMDDecode(x, block, 64);
213
214 for(j = 0; j < 16; j++) {
215 tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
216 a = d; d = c; c = b; b = tmp;
217 tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
218 aa = dd; dd = cc; cc = bb; bb = tmp;
219 }
220
221 for(j = 16; j < 32; j++) {
222 tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
223 a = d; d = c; c = b; b = tmp;
224 tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
225 aa = dd; dd = cc; cc = bb; bb = tmp;
226 }
227
228 for(j = 32; j < 48; j++) {
229 tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
230 a = d; d = c; c = b; b = tmp;
231 tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
232 aa = dd; dd = cc; cc = bb; bb = tmp;
233 }
234
235 for(j = 48; j < 64; j++) {
236 tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
237 a = d; d = c; c = b; b = tmp;
238 tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
239 aa = dd; dd = cc; cc = bb; bb = tmp;
240 }
241
242 tmp = state[1] + c + dd;
243 state[1] = state[2] + d + aa;
244 state[2] = state[3] + a + bb;
245 state[3] = state[0] + b + cc;
246 state[0] = tmp;
247
248 tmp = 0;
249 ZEND_SECURE_ZERO(x, sizeof(x));
250 }
251 /* }}} */
252
253 /* {{{ PHP_RIPEMD128Update
254 ripemd128 block update operation. Continues a ripemd128 message-digest
255 operation, processing another message block, and updating the
256 context.
257 */
PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context,const unsigned char * input,unsigned int inputLen)258 PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context, const unsigned char *input, unsigned int inputLen)
259 {
260 unsigned int i, index, partLen;
261
262 /* Compute number of bytes mod 64 */
263 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
264
265 /* Update number of bits */
266 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
267 context->count[1]++;
268 }
269 context->count[1] += ((uint32_t) inputLen >> 29);
270
271 partLen = 64 - index;
272
273 /* Transform as many times as possible.
274 */
275 if (inputLen >= partLen) {
276 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
277 RIPEMD128Transform(context->state, context->buffer);
278
279 for (i = partLen; i + 63 < inputLen; i += 64) {
280 RIPEMD128Transform(context->state, &input[i]);
281 }
282
283 index = 0;
284 } else {
285 i = 0;
286 }
287
288 /* Buffer remaining input */
289 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
290 }
291 /* }}} */
292
293 /* {{{ RIPEMD256Transform
294 * ripemd256 basic transformation. Transforms state based on block.
295 */
RIPEMD256Transform(uint32_t state[8],const unsigned char block[64])296 static void RIPEMD256Transform(uint32_t state[8], const unsigned char block[64])
297 {
298 uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
299 uint32_t aa = state[4], bb = state[5], cc = state[6], dd = state[7];
300 uint32_t tmp, x[16];
301 int j;
302
303 RIPEMDDecode(x, block, 64);
304
305 for(j = 0; j < 16; j++) {
306 tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
307 a = d; d = c; c = b; b = tmp;
308 tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
309 aa = dd; dd = cc; cc = bb; bb = tmp;
310 }
311 tmp = a; a = aa; aa = tmp;
312
313 for(j = 16; j < 32; j++) {
314 tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
315 a = d; d = c; c = b; b = tmp;
316 tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
317 aa = dd; dd = cc; cc = bb; bb = tmp;
318 }
319 tmp = b; b = bb; bb = tmp;
320
321 for(j = 32; j < 48; j++) {
322 tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
323 a = d; d = c; c = b; b = tmp;
324 tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
325 aa = dd; dd = cc; cc = bb; bb = tmp;
326 }
327 tmp = c; c = cc; cc = tmp;
328
329 for(j = 48; j < 64; j++) {
330 tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
331 a = d; d = c; c = b; b = tmp;
332 tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
333 aa = dd; dd = cc; cc = bb; bb = tmp;
334 }
335 tmp = d; d = dd; dd = tmp;
336
337 state[0] += a;
338 state[1] += b;
339 state[2] += c;
340 state[3] += d;
341 state[4] += aa;
342 state[5] += bb;
343 state[6] += cc;
344 state[7] += dd;
345
346 tmp = 0;
347 ZEND_SECURE_ZERO(x, sizeof(x));
348 }
349 /* }}} */
350
351 /* {{{ PHP_RIPEMD256Update
352 ripemd256 block update operation. Continues a ripemd256 message-digest
353 operation, processing another message block, and updating the
354 context.
355 */
PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context,const unsigned char * input,unsigned int inputLen)356 PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, unsigned int inputLen)
357 {
358 unsigned int i, index, partLen;
359
360 /* Compute number of bytes mod 64 */
361 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
362
363 /* Update number of bits */
364 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
365 context->count[1]++;
366 }
367 context->count[1] += ((uint32_t) inputLen >> 29);
368
369 partLen = 64 - index;
370
371 /* Transform as many times as possible.
372 */
373 if (inputLen >= partLen) {
374 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
375 RIPEMD256Transform(context->state, context->buffer);
376
377 for (i = partLen; i + 63 < inputLen; i += 64) {
378 RIPEMD256Transform(context->state, &input[i]);
379 }
380
381 index = 0;
382 } else {
383 i = 0;
384 }
385
386 /* Buffer remaining input */
387 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
388 }
389 /* }}} */
390
391 /* {{{ RIPEMD160Transform
392 * ripemd160 basic transformation. Transforms state based on block.
393 */
RIPEMD160Transform(uint32_t state[5],const unsigned char block[64])394 static void RIPEMD160Transform(uint32_t state[5], const unsigned char block[64])
395 {
396 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
397 uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
398 uint32_t tmp, x[16];
399 int j;
400
401 RIPEMDDecode(x, block, 64);
402
403 for(j = 0; j < 16; j++) {
404 tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
405 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
406 tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
407 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
408 }
409
410 for(j = 16; j < 32; j++) {
411 tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
412 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
413 tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
414 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
415 }
416
417 for(j = 32; j < 48; j++) {
418 tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
419 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
420 tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
421 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
422 }
423
424 for(j = 48; j < 64; j++) {
425 tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
426 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
427 tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
428 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
429 }
430
431 for(j = 64; j < 80; j++) {
432 tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
433 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
434 tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
435 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
436 }
437
438 tmp = state[1] + c + dd;
439 state[1] = state[2] + d + ee;
440 state[2] = state[3] + e + aa;
441 state[3] = state[4] + a + bb;
442 state[4] = state[0] + b + cc;
443 state[0] = tmp;
444
445 tmp = 0;
446 ZEND_SECURE_ZERO(x, sizeof(x));
447 }
448 /* }}} */
449
450 /* {{{ PHP_RIPEMD160Update
451 ripemd160 block update operation. Continues a ripemd160 message-digest
452 operation, processing another message block, and updating the
453 context.
454 */
PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context,const unsigned char * input,unsigned int inputLen)455 PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, unsigned int inputLen)
456 {
457 unsigned int i, index, partLen;
458
459 /* Compute number of bytes mod 64 */
460 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
461
462 /* Update number of bits */
463 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
464 context->count[1]++;
465 }
466 context->count[1] += ((uint32_t) inputLen >> 29);
467
468 partLen = 64 - index;
469
470 /* Transform as many times as possible.
471 */
472 if (inputLen >= partLen) {
473 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
474 RIPEMD160Transform(context->state, context->buffer);
475
476 for (i = partLen; i + 63 < inputLen; i += 64) {
477 RIPEMD160Transform(context->state, &input[i]);
478 }
479
480 index = 0;
481 } else {
482 i = 0;
483 }
484
485 /* Buffer remaining input */
486 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
487 }
488 /* }}} */
489
490 /* {{{ RIPEMD320Transform
491 * ripemd320 basic transformation. Transforms state based on block.
492 */
RIPEMD320Transform(uint32_t state[10],const unsigned char block[64])493 static void RIPEMD320Transform(uint32_t state[10], const unsigned char block[64])
494 {
495 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
496 uint32_t aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
497 uint32_t tmp, x[16];
498 int j;
499
500 RIPEMDDecode(x, block, 64);
501
502 for(j = 0; j < 16; j++) {
503 tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
504 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
505 tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
506 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
507 }
508 tmp = b; b = bb; bb = tmp;
509
510 for(j = 16; j < 32; j++) {
511 tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
512 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
513 tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
514 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
515 }
516 tmp = d; d = dd; dd = tmp;
517
518 for(j = 32; j < 48; j++) {
519 tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
520 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
521 tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
522 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
523 }
524 tmp = a; a = aa; aa = tmp;
525
526 for(j = 48; j < 64; j++) {
527 tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
528 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
529 tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
530 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
531 }
532 tmp = c; c = cc; cc = tmp;
533
534 for(j = 64; j < 80; j++) {
535 tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
536 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
537 tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
538 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
539 }
540 tmp = e; e = ee; ee = tmp;
541
542 state[0] += a;
543 state[1] += b;
544 state[2] += c;
545 state[3] += d;
546 state[4] += e;
547 state[5] += aa;
548 state[6] += bb;
549 state[7] += cc;
550 state[8] += dd;
551 state[9] += ee;
552
553 tmp = 0;
554 ZEND_SECURE_ZERO(x, sizeof(x));
555 }
556 /* }}} */
557
558 /* {{{ PHP_RIPEMD320Update
559 ripemd320 block update operation. Continues a ripemd320 message-digest
560 operation, processing another message block, and updating the
561 context.
562 */
PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context,const unsigned char * input,unsigned int inputLen)563 PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, unsigned int inputLen)
564 {
565 unsigned int i, index, partLen;
566
567 /* Compute number of bytes mod 64 */
568 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
569
570 /* Update number of bits */
571 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
572 context->count[1]++;
573 }
574 context->count[1] += ((uint32_t) inputLen >> 29);
575
576 partLen = 64 - index;
577
578 /* Transform as many times as possible.
579 */
580 if (inputLen >= partLen) {
581 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
582 RIPEMD320Transform(context->state, context->buffer);
583
584 for (i = partLen; i + 63 < inputLen; i += 64) {
585 RIPEMD320Transform(context->state, &input[i]);
586 }
587
588 index = 0;
589 } else {
590 i = 0;
591 }
592
593 /* Buffer remaining input */
594 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
595 }
596 /* }}} */
597
598 static const unsigned char PADDING[64] =
599 {
600 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
601 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
602 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
603 };
604
605 /* {{{ RIPEMDEncode
606 Encodes input (uint32_t) into output (unsigned char). Assumes len is
607 a multiple of 4.
608 */
RIPEMDEncode(unsigned char * output,uint32_t * input,unsigned int len)609 static void RIPEMDEncode(unsigned char *output, uint32_t *input, unsigned int len)
610 {
611 unsigned int i, j;
612
613 for (i = 0, j = 0; j < len; i++, j += 4) {
614 output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
615 output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
616 output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
617 output[j + 0] = (unsigned char) (input[i] & 0xff);
618 }
619 }
620 /* }}} */
621
622 /* {{{ PHP_RIPEMD128Final
623 ripemd128 finalization. Ends a ripemd128 message-digest operation, writing the
624 the message digest and zeroizing the context.
625 */
PHP_RIPEMD128Final(unsigned char digest[16],PHP_RIPEMD128_CTX * context)626 PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
627 {
628 unsigned char bits[8];
629 unsigned int index, padLen;
630
631 /* Save number of bits */
632 bits[0] = (unsigned char) (context->count[0] & 0xFF);
633 bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
634 bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
635 bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
636 bits[4] = (unsigned char) (context->count[1] & 0xFF);
637 bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
638 bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
639 bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
640
641 /* Pad out to 56 mod 64.
642 */
643 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
644 padLen = (index < 56) ? (56 - index) : (120 - index);
645 PHP_RIPEMD128Update(context, PADDING, padLen);
646
647 /* Append length (before padding) */
648 PHP_RIPEMD128Update(context, bits, 8);
649
650 /* Store state in digest */
651 RIPEMDEncode(digest, context->state, 16);
652
653 /* Zeroize sensitive information.
654 */
655 ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
656 }
657 /* }}} */
658
659 /* {{{ PHP_RIPEMD256Final
660 ripemd256 finalization. Ends a ripemd256 message-digest operation, writing the
661 the message digest and zeroizing the context.
662 */
PHP_RIPEMD256Final(unsigned char digest[32],PHP_RIPEMD256_CTX * context)663 PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
664 {
665 unsigned char bits[8];
666 unsigned int index, padLen;
667
668 /* Save number of bits */
669 bits[0] = (unsigned char) (context->count[0] & 0xFF);
670 bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
671 bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
672 bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
673 bits[4] = (unsigned char) (context->count[1] & 0xFF);
674 bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
675 bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
676 bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
677
678 /* Pad out to 56 mod 64.
679 */
680 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
681 padLen = (index < 56) ? (56 - index) : (120 - index);
682 PHP_RIPEMD256Update(context, PADDING, padLen);
683
684 /* Append length (before padding) */
685 PHP_RIPEMD256Update(context, bits, 8);
686
687 /* Store state in digest */
688 RIPEMDEncode(digest, context->state, 32);
689
690 /* Zeroize sensitive information.
691 */
692 ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
693 }
694 /* }}} */
695
696 /* {{{ PHP_RIPEMD160Final
697 ripemd160 finalization. Ends a ripemd160 message-digest operation, writing the
698 the message digest and zeroizing the context.
699 */
PHP_RIPEMD160Final(unsigned char digest[20],PHP_RIPEMD160_CTX * context)700 PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
701 {
702 unsigned char bits[8];
703 unsigned int index, padLen;
704
705 /* Save number of bits */
706 bits[0] = (unsigned char) (context->count[0] & 0xFF);
707 bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
708 bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
709 bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
710 bits[4] = (unsigned char) (context->count[1] & 0xFF);
711 bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
712 bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
713 bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
714
715 /* Pad out to 56 mod 64.
716 */
717 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
718 padLen = (index < 56) ? (56 - index) : (120 - index);
719 PHP_RIPEMD160Update(context, PADDING, padLen);
720
721 /* Append length (before padding) */
722 PHP_RIPEMD160Update(context, bits, 8);
723
724 /* Store state in digest */
725 RIPEMDEncode(digest, context->state, 20);
726
727 /* Zeroize sensitive information.
728 */
729 ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
730 }
731 /* }}} */
732
733 /* {{{ PHP_RIPEMD320Final
734 ripemd320 finalization. Ends a ripemd320 message-digest operation, writing the
735 the message digest and zeroizing the context.
736 */
PHP_RIPEMD320Final(unsigned char digest[40],PHP_RIPEMD320_CTX * context)737 PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
738 {
739 unsigned char bits[8];
740 unsigned int index, padLen;
741
742 /* Save number of bits */
743 bits[0] = (unsigned char) (context->count[0] & 0xFF);
744 bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
745 bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
746 bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
747 bits[4] = (unsigned char) (context->count[1] & 0xFF);
748 bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
749 bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
750 bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
751
752 /* Pad out to 56 mod 64.
753 */
754 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
755 padLen = (index < 56) ? (56 - index) : (120 - index);
756 PHP_RIPEMD320Update(context, PADDING, padLen);
757
758 /* Append length (before padding) */
759 PHP_RIPEMD320Update(context, bits, 8);
760
761 /* Store state in digest */
762 RIPEMDEncode(digest, context->state, 40);
763
764 /* Zeroize sensitive information.
765 */
766 ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
767 }
768 /* }}} */
769
770 /*
771 * Local variables:
772 * tab-width: 4
773 * c-basic-offset: 4
774 * End:
775 * vim600: sw=4 ts=4 fdm=marker
776 * vim<600: sw=4 ts=4
777 */
778