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