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 index, partLen;
275 size_t i;
276
277 /* Compute number of bytes mod 64 */
278 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
279
280 /* Update number of bits */
281 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
282 context->count[1]++;
283 }
284 context->count[1] += (uint32_t) (inputLen >> 29);
285
286 partLen = 64 - index;
287
288 /* Transform as many times as possible.
289 */
290 if (inputLen >= partLen) {
291 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
292 RIPEMD128Transform(context->state, context->buffer);
293
294 for (i = partLen; i + 63 < inputLen; i += 64) {
295 RIPEMD128Transform(context->state, &input[i]);
296 }
297
298 index = 0;
299 } else {
300 i = 0;
301 }
302
303 /* Buffer remaining input */
304 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
305 }
306 /* }}} */
307
308 /* {{{ RIPEMD256Transform
309 * ripemd256 basic transformation. Transforms state based on block.
310 */
RIPEMD256Transform(uint32_t state[8],const unsigned char block[64])311 static void RIPEMD256Transform(uint32_t state[8], const unsigned char block[64])
312 {
313 uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
314 uint32_t aa = state[4], bb = state[5], cc = state[6], dd = state[7];
315 uint32_t tmp, x[16];
316 int j;
317
318 RIPEMDDecode(x, block, 64);
319
320 for(j = 0; j < 16; j++) {
321 tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
322 a = d; d = c; c = b; b = tmp;
323 tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
324 aa = dd; dd = cc; cc = bb; bb = tmp;
325 }
326 tmp = a; a = aa; aa = tmp;
327
328 for(j = 16; j < 32; j++) {
329 tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
330 a = d; d = c; c = b; b = tmp;
331 tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
332 aa = dd; dd = cc; cc = bb; bb = tmp;
333 }
334 tmp = b; b = bb; bb = tmp;
335
336 for(j = 32; j < 48; j++) {
337 tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
338 a = d; d = c; c = b; b = tmp;
339 tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
340 aa = dd; dd = cc; cc = bb; bb = tmp;
341 }
342 tmp = c; c = cc; cc = tmp;
343
344 for(j = 48; j < 64; j++) {
345 tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
346 a = d; d = c; c = b; b = tmp;
347 tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
348 aa = dd; dd = cc; cc = bb; bb = tmp;
349 }
350 tmp = d; d = dd; dd = tmp;
351
352 state[0] += a;
353 state[1] += b;
354 state[2] += c;
355 state[3] += d;
356 state[4] += aa;
357 state[5] += bb;
358 state[6] += cc;
359 state[7] += dd;
360
361 tmp = 0;
362 ZEND_SECURE_ZERO(x, sizeof(x));
363 }
364 /* }}} */
365
366 /* {{{ PHP_RIPEMD256Update
367 ripemd256 block update operation. Continues a ripemd256 message-digest
368 operation, processing another message block, and updating the
369 context.
370 */
PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context,const unsigned char * input,size_t inputLen)371 PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, size_t inputLen)
372 {
373 unsigned int index, partLen;
374 size_t i;
375
376 /* Compute number of bytes mod 64 */
377 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
378
379 /* Update number of bits */
380 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
381 context->count[1]++;
382 }
383 context->count[1] += (uint32_t) (inputLen >> 29);
384
385 partLen = 64 - index;
386
387 /* Transform as many times as possible.
388 */
389 if (inputLen >= partLen) {
390 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
391 RIPEMD256Transform(context->state, context->buffer);
392
393 for (i = partLen; i + 63 < inputLen; i += 64) {
394 RIPEMD256Transform(context->state, &input[i]);
395 }
396
397 index = 0;
398 } else {
399 i = 0;
400 }
401
402 /* Buffer remaining input */
403 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
404 }
405 /* }}} */
406
407 /* {{{ RIPEMD160Transform
408 * ripemd160 basic transformation. Transforms state based on block.
409 */
RIPEMD160Transform(uint32_t state[5],const unsigned char block[64])410 static void RIPEMD160Transform(uint32_t state[5], const unsigned char block[64])
411 {
412 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
413 uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
414 uint32_t tmp, x[16];
415 int j;
416
417 RIPEMDDecode(x, block, 64);
418
419 for(j = 0; j < 16; j++) {
420 tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
421 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
422 tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
423 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
424 }
425
426 for(j = 16; j < 32; j++) {
427 tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
428 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
429 tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
430 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
431 }
432
433 for(j = 32; j < 48; j++) {
434 tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
435 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
436 tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
437 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
438 }
439
440 for(j = 48; j < 64; j++) {
441 tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
442 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
443 tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
444 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
445 }
446
447 for(j = 64; j < 80; j++) {
448 tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
449 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
450 tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
451 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
452 }
453
454 tmp = state[1] + c + dd;
455 state[1] = state[2] + d + ee;
456 state[2] = state[3] + e + aa;
457 state[3] = state[4] + a + bb;
458 state[4] = state[0] + b + cc;
459 state[0] = tmp;
460
461 tmp = 0;
462 ZEND_SECURE_ZERO(x, sizeof(x));
463 }
464 /* }}} */
465
466 /* {{{ PHP_RIPEMD160Update
467 ripemd160 block update operation. Continues a ripemd160 message-digest
468 operation, processing another message block, and updating the
469 context.
470 */
PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context,const unsigned char * input,size_t inputLen)471 PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, size_t inputLen)
472 {
473 unsigned int index, partLen;
474 size_t i;
475
476 /* Compute number of bytes mod 64 */
477 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
478
479 /* Update number of bits */
480 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
481 context->count[1]++;
482 }
483 context->count[1] += (uint32_t) (inputLen >> 29);
484
485 partLen = 64 - index;
486
487 /* Transform as many times as possible.
488 */
489 if (inputLen >= partLen) {
490 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
491 RIPEMD160Transform(context->state, context->buffer);
492
493 for (i = partLen; i + 63 < inputLen; i += 64) {
494 RIPEMD160Transform(context->state, &input[i]);
495 }
496
497 index = 0;
498 } else {
499 i = 0;
500 }
501
502 /* Buffer remaining input */
503 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
504 }
505 /* }}} */
506
507 /* {{{ RIPEMD320Transform
508 * ripemd320 basic transformation. Transforms state based on block.
509 */
RIPEMD320Transform(uint32_t state[10],const unsigned char block[64])510 static void RIPEMD320Transform(uint32_t state[10], const unsigned char block[64])
511 {
512 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
513 uint32_t aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
514 uint32_t tmp, x[16];
515 int j;
516
517 RIPEMDDecode(x, block, 64);
518
519 for(j = 0; j < 16; j++) {
520 tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
521 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
522 tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
523 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
524 }
525 tmp = b; b = bb; bb = tmp;
526
527 for(j = 16; j < 32; j++) {
528 tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
529 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
530 tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
531 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
532 }
533 tmp = d; d = dd; dd = tmp;
534
535 for(j = 32; j < 48; j++) {
536 tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
537 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
538 tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
539 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
540 }
541 tmp = a; a = aa; aa = tmp;
542
543 for(j = 48; j < 64; j++) {
544 tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
545 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
546 tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
547 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
548 }
549 tmp = c; c = cc; cc = tmp;
550
551 for(j = 64; j < 80; j++) {
552 tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
553 a = e; e = d; d = ROL(10, c); c = b; b = tmp;
554 tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
555 aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
556 }
557 tmp = e; e = ee; ee = tmp;
558
559 state[0] += a;
560 state[1] += b;
561 state[2] += c;
562 state[3] += d;
563 state[4] += e;
564 state[5] += aa;
565 state[6] += bb;
566 state[7] += cc;
567 state[8] += dd;
568 state[9] += ee;
569
570 tmp = 0;
571 ZEND_SECURE_ZERO(x, sizeof(x));
572 }
573 /* }}} */
574
575 /* {{{ PHP_RIPEMD320Update
576 ripemd320 block update operation. Continues a ripemd320 message-digest
577 operation, processing another message block, and updating the
578 context.
579 */
PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context,const unsigned char * input,size_t inputLen)580 PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, size_t inputLen)
581 {
582 unsigned int index, partLen;
583 size_t i;
584
585 /* Compute number of bytes mod 64 */
586 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
587
588 /* Update number of bits */
589 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
590 context->count[1]++;
591 }
592 context->count[1] += (uint32_t) (inputLen >> 29);
593
594 partLen = 64 - index;
595
596 /* Transform as many times as possible.
597 */
598 if (inputLen >= partLen) {
599 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
600 RIPEMD320Transform(context->state, context->buffer);
601
602 for (i = partLen; i + 63 < inputLen; i += 64) {
603 RIPEMD320Transform(context->state, &input[i]);
604 }
605
606 index = 0;
607 } else {
608 i = 0;
609 }
610
611 /* Buffer remaining input */
612 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
613 }
614 /* }}} */
615
616 static const unsigned char PADDING[64] =
617 {
618 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
619 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
620 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
621 };
622
623 /* {{{ RIPEMDEncode
624 Encodes input (uint32_t) into output (unsigned char). Assumes len is
625 a multiple of 4.
626 */
RIPEMDEncode(unsigned char * output,uint32_t * input,unsigned int len)627 static void RIPEMDEncode(unsigned char *output, uint32_t *input, unsigned int len)
628 {
629 unsigned int i, j;
630
631 for (i = 0, j = 0; j < len; i++, j += 4) {
632 output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
633 output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
634 output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
635 output[j + 0] = (unsigned char) (input[i] & 0xff);
636 }
637 }
638 /* }}} */
639
640 /* {{{ PHP_RIPEMD128Final
641 ripemd128 finalization. Ends a ripemd128 message-digest operation, writing the
642 the message digest and zeroizing the context.
643 */
PHP_RIPEMD128Final(unsigned char digest[16],PHP_RIPEMD128_CTX * context)644 PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
645 {
646 unsigned char bits[8];
647 unsigned int index, padLen;
648
649 /* Save number of bits */
650 bits[0] = (unsigned char) (context->count[0] & 0xFF);
651 bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
652 bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
653 bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
654 bits[4] = (unsigned char) (context->count[1] & 0xFF);
655 bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
656 bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
657 bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
658
659 /* Pad out to 56 mod 64.
660 */
661 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
662 padLen = (index < 56) ? (56 - index) : (120 - index);
663 PHP_RIPEMD128Update(context, PADDING, padLen);
664
665 /* Append length (before padding) */
666 PHP_RIPEMD128Update(context, bits, 8);
667
668 /* Store state in digest */
669 RIPEMDEncode(digest, context->state, 16);
670
671 /* Zeroize sensitive information.
672 */
673 ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
674 }
675 /* }}} */
676
677 /* {{{ PHP_RIPEMD256Final
678 ripemd256 finalization. Ends a ripemd256 message-digest operation, writing the
679 the message digest and zeroizing the context.
680 */
PHP_RIPEMD256Final(unsigned char digest[32],PHP_RIPEMD256_CTX * context)681 PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
682 {
683 unsigned char bits[8];
684 unsigned int index, padLen;
685
686 /* Save number of bits */
687 bits[0] = (unsigned char) (context->count[0] & 0xFF);
688 bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
689 bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
690 bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
691 bits[4] = (unsigned char) (context->count[1] & 0xFF);
692 bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
693 bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
694 bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
695
696 /* Pad out to 56 mod 64.
697 */
698 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
699 padLen = (index < 56) ? (56 - index) : (120 - index);
700 PHP_RIPEMD256Update(context, PADDING, padLen);
701
702 /* Append length (before padding) */
703 PHP_RIPEMD256Update(context, bits, 8);
704
705 /* Store state in digest */
706 RIPEMDEncode(digest, context->state, 32);
707
708 /* Zeroize sensitive information.
709 */
710 ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
711 }
712 /* }}} */
713
714 /* {{{ PHP_RIPEMD160Final
715 ripemd160 finalization. Ends a ripemd160 message-digest operation, writing the
716 the message digest and zeroizing the context.
717 */
PHP_RIPEMD160Final(unsigned char digest[20],PHP_RIPEMD160_CTX * context)718 PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
719 {
720 unsigned char bits[8];
721 unsigned int index, padLen;
722
723 /* Save number of bits */
724 bits[0] = (unsigned char) (context->count[0] & 0xFF);
725 bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
726 bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
727 bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
728 bits[4] = (unsigned char) (context->count[1] & 0xFF);
729 bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
730 bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
731 bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
732
733 /* Pad out to 56 mod 64.
734 */
735 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
736 padLen = (index < 56) ? (56 - index) : (120 - index);
737 PHP_RIPEMD160Update(context, PADDING, padLen);
738
739 /* Append length (before padding) */
740 PHP_RIPEMD160Update(context, bits, 8);
741
742 /* Store state in digest */
743 RIPEMDEncode(digest, context->state, 20);
744
745 /* Zeroize sensitive information.
746 */
747 ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
748 }
749 /* }}} */
750
751 /* {{{ PHP_RIPEMD320Final
752 ripemd320 finalization. Ends a ripemd320 message-digest operation, writing the
753 the message digest and zeroizing the context.
754 */
PHP_RIPEMD320Final(unsigned char digest[40],PHP_RIPEMD320_CTX * context)755 PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
756 {
757 unsigned char bits[8];
758 unsigned int index, padLen;
759
760 /* Save number of bits */
761 bits[0] = (unsigned char) (context->count[0] & 0xFF);
762 bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
763 bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
764 bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
765 bits[4] = (unsigned char) (context->count[1] & 0xFF);
766 bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
767 bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
768 bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
769
770 /* Pad out to 56 mod 64.
771 */
772 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
773 padLen = (index < 56) ? (56 - index) : (120 - index);
774 PHP_RIPEMD320Update(context, PADDING, padLen);
775
776 /* Append length (before padding) */
777 PHP_RIPEMD320Update(context, bits, 8);
778
779 /* Store state in digest */
780 RIPEMDEncode(digest, context->state, 40);
781
782 /* Zeroize sensitive information.
783 */
784 ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
785 }
786 /* }}} */
787