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