1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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: hash_ripemd.c 276986 2009-03-10 23:40:06Z helly $ */
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 : */
71 : PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context)
72 18 : {
73 18 : context->count[0] = context->count[1] = 0;
74 : /* Load magic initialization constants.
75 : */
76 18 : context->state[0] = 0x67452301;
77 18 : context->state[1] = 0xEFCDAB89;
78 18 : context->state[2] = 0x98BADCFE;
79 18 : context->state[3] = 0x10325476;
80 18 : }
81 : /* }}} */
82 :
83 : /* {{{ PHP_RIPEMD256Init
84 : * ripemd256 initialization. Begins a ripemd256 operation, writing a new context.
85 : */
86 : PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context)
87 18 : {
88 18 : context->count[0] = context->count[1] = 0;
89 : /* Load magic initialization constants.
90 : */
91 18 : context->state[0] = 0x67452301;
92 18 : context->state[1] = 0xEFCDAB89;
93 18 : context->state[2] = 0x98BADCFE;
94 18 : context->state[3] = 0x10325476;
95 18 : context->state[4] = 0x76543210;
96 18 : context->state[5] = 0xFEDCBA98;
97 18 : context->state[6] = 0x89ABCDEF;
98 18 : context->state[7] = 0x01234567;
99 18 : }
100 : /* }}} */
101 :
102 : /* {{{ PHP_RIPEMD160Init
103 : * ripemd160 initialization. Begins a ripemd160 operation, writing a new context.
104 : */
105 : PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context)
106 25 : {
107 25 : context->count[0] = context->count[1] = 0;
108 : /* Load magic initialization constants.
109 : */
110 25 : context->state[0] = 0x67452301;
111 25 : context->state[1] = 0xEFCDAB89;
112 25 : context->state[2] = 0x98BADCFE;
113 25 : context->state[3] = 0x10325476;
114 25 : context->state[4] = 0xC3D2E1F0;
115 25 : }
116 : /* }}} */
117 :
118 : /* {{{ PHP_RIPEMD320Init
119 : * ripemd320 initialization. Begins a ripemd320 operation, writing a new context.
120 : */
121 : PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context)
122 18 : {
123 18 : context->count[0] = context->count[1] = 0;
124 : /* Load magic initialization constants.
125 : */
126 18 : context->state[0] = 0x67452301;
127 18 : context->state[1] = 0xEFCDAB89;
128 18 : context->state[2] = 0x98BADCFE;
129 18 : context->state[3] = 0x10325476;
130 18 : context->state[4] = 0xC3D2E1F0;
131 18 : context->state[5] = 0x76543210;
132 18 : context->state[6] = 0xFEDCBA98;
133 18 : context->state[7] = 0x89ABCDEF;
134 18 : context->state[8] = 0x01234567;
135 18 : context->state[9] = 0x3C2D1E0F;
136 18 : }
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 : */
190 : static void RIPEMDDecode(php_hash_uint32 *output, const unsigned char *input, unsigned int len)
191 62632 : {
192 : unsigned int i, j;
193 :
194 1064744 : for (i = 0, j = 0; j < len; i++, j += 4)
195 1002112 : 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 62632 : }
198 : /* }}} */
199 :
200 : /* {{{ RIPEMD128Transform
201 : * ripemd128 basic transformation. Transforms state based on block.
202 : */
203 : static void RIPEMD128Transform(php_hash_uint32 state[4], const unsigned char block[64])
204 15654 : {
205 15654 : php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
206 15654 : 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 15654 : RIPEMDDecode(x, block, 64);
211 :
212 266118 : for(j = 0; j < 16; j++) {
213 250464 : tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
214 250464 : a = d; d = c; c = b; b = tmp;
215 250464 : tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
216 250464 : aa = dd; dd = cc; cc = bb; bb = tmp;
217 : }
218 :
219 266118 : for(j = 16; j < 32; j++) {
220 250464 : tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
221 250464 : a = d; d = c; c = b; b = tmp;
222 250464 : tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
223 250464 : aa = dd; dd = cc; cc = bb; bb = tmp;
224 : }
225 :
226 266118 : for(j = 32; j < 48; j++) {
227 250464 : tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
228 250464 : a = d; d = c; c = b; b = tmp;
229 250464 : tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
230 250464 : aa = dd; dd = cc; cc = bb; bb = tmp;
231 : }
232 :
233 266118 : for(j = 48; j < 64; j++) {
234 250464 : tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
235 250464 : a = d; d = c; c = b; b = tmp;
236 250464 : tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
237 250464 : aa = dd; dd = cc; cc = bb; bb = tmp;
238 : }
239 :
240 15654 : tmp = state[1] + c + dd;
241 15654 : state[1] = state[2] + d + aa;
242 15654 : state[2] = state[3] + a + bb;
243 15654 : state[3] = state[0] + b + cc;
244 15654 : state[0] = tmp;
245 :
246 15654 : tmp = 0;
247 15654 : memset(x, 0, sizeof(x));
248 15654 : }
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 : */
256 : PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context, const unsigned char *input, unsigned int inputLen)
257 57 : {
258 : unsigned int i, index, partLen;
259 :
260 : /* Compute number of bytes mod 64 */
261 57 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
262 :
263 : /* Update number of bits */
264 57 : if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
265 0 : context->count[1]++;
266 : }
267 57 : context->count[1] += ((php_hash_uint32) inputLen >> 29);
268 :
269 57 : partLen = 64 - index;
270 :
271 : /* Transform as many times as possible.
272 : */
273 57 : if (inputLen >= partLen) {
274 30 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
275 30 : RIPEMD128Transform(context->state, context->buffer);
276 :
277 15654 : for (i = partLen; i + 63 < inputLen; i += 64) {
278 15624 : RIPEMD128Transform(context->state, &input[i]);
279 : }
280 :
281 30 : index = 0;
282 : } else {
283 27 : i = 0;
284 : }
285 :
286 : /* Buffer remaining input */
287 57 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
288 57 : }
289 : /* }}} */
290 :
291 : /* {{{ RIPEMD256Transform
292 : * ripemd256 basic transformation. Transforms state based on block.
293 : */
294 : static void RIPEMD256Transform(php_hash_uint32 state[8], const unsigned char block[64])
295 15654 : {
296 15654 : php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
297 15654 : 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 15654 : RIPEMDDecode(x, block, 64);
302 :
303 266118 : for(j = 0; j < 16; j++) {
304 250464 : tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
305 250464 : a = d; d = c; c = b; b = tmp;
306 250464 : tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
307 250464 : aa = dd; dd = cc; cc = bb; bb = tmp;
308 : }
309 15654 : tmp = a; a = aa; aa = tmp;
310 :
311 266118 : for(j = 16; j < 32; j++) {
312 250464 : tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
313 250464 : a = d; d = c; c = b; b = tmp;
314 250464 : tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
315 250464 : aa = dd; dd = cc; cc = bb; bb = tmp;
316 : }
317 15654 : tmp = b; b = bb; bb = tmp;
318 :
319 266118 : for(j = 32; j < 48; j++) {
320 250464 : tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
321 250464 : a = d; d = c; c = b; b = tmp;
322 250464 : tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
323 250464 : aa = dd; dd = cc; cc = bb; bb = tmp;
324 : }
325 15654 : tmp = c; c = cc; cc = tmp;
326 :
327 266118 : for(j = 48; j < 64; j++) {
328 250464 : tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
329 250464 : a = d; d = c; c = b; b = tmp;
330 250464 : tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
331 250464 : aa = dd; dd = cc; cc = bb; bb = tmp;
332 : }
333 15654 : tmp = d; d = dd; dd = tmp;
334 :
335 15654 : state[0] += a;
336 15654 : state[1] += b;
337 15654 : state[2] += c;
338 15654 : state[3] += d;
339 15654 : state[4] += aa;
340 15654 : state[5] += bb;
341 15654 : state[6] += cc;
342 15654 : state[7] += dd;
343 :
344 15654 : tmp = 0;
345 15654 : memset(x, 0, sizeof(x));
346 15654 : }
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 : */
354 : PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, unsigned int inputLen)
355 57 : {
356 : unsigned int i, index, partLen;
357 :
358 : /* Compute number of bytes mod 64 */
359 57 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
360 :
361 : /* Update number of bits */
362 57 : if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
363 0 : context->count[1]++;
364 : }
365 57 : context->count[1] += ((php_hash_uint32) inputLen >> 29);
366 :
367 57 : partLen = 64 - index;
368 :
369 : /* Transform as many times as possible.
370 : */
371 57 : if (inputLen >= partLen) {
372 30 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
373 30 : RIPEMD256Transform(context->state, context->buffer);
374 :
375 15654 : for (i = partLen; i + 63 < inputLen; i += 64) {
376 15624 : RIPEMD256Transform(context->state, &input[i]);
377 : }
378 :
379 30 : index = 0;
380 : } else {
381 27 : i = 0;
382 : }
383 :
384 : /* Buffer remaining input */
385 57 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
386 57 : }
387 : /* }}} */
388 :
389 : /* {{{ RIPEMD160Transform
390 : * ripemd160 basic transformation. Transforms state based on block.
391 : */
392 : static void RIPEMD160Transform(php_hash_uint32 state[5], const unsigned char block[64])
393 15670 : {
394 15670 : php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
395 15670 : 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 15670 : RIPEMDDecode(x, block, 64);
400 :
401 266390 : for(j = 0; j < 16; j++) {
402 250720 : tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
403 250720 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
404 250720 : tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
405 250720 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
406 : }
407 :
408 266390 : for(j = 16; j < 32; j++) {
409 250720 : tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
410 250720 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
411 250720 : tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
412 250720 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
413 : }
414 :
415 266390 : for(j = 32; j < 48; j++) {
416 250720 : tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
417 250720 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
418 250720 : tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
419 250720 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
420 : }
421 :
422 266390 : for(j = 48; j < 64; j++) {
423 250720 : tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
424 250720 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
425 250720 : tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
426 250720 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
427 : }
428 :
429 266390 : for(j = 64; j < 80; j++) {
430 250720 : tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
431 250720 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
432 250720 : tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
433 250720 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
434 : }
435 :
436 15670 : tmp = state[1] + c + dd;
437 15670 : state[1] = state[2] + d + ee;
438 15670 : state[2] = state[3] + e + aa;
439 15670 : state[3] = state[4] + a + bb;
440 15670 : state[4] = state[0] + b + cc;
441 15670 : state[0] = tmp;
442 :
443 15670 : tmp = 0;
444 15670 : memset(x, 0, sizeof(x));
445 15670 : }
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 : */
453 : PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, unsigned int inputLen)
454 90 : {
455 : unsigned int i, index, partLen;
456 :
457 : /* Compute number of bytes mod 64 */
458 90 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
459 :
460 : /* Update number of bits */
461 90 : if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
462 0 : context->count[1]++;
463 : }
464 90 : context->count[1] += ((php_hash_uint32) inputLen >> 29);
465 :
466 90 : partLen = 64 - index;
467 :
468 : /* Transform as many times as possible.
469 : */
470 90 : if (inputLen >= partLen) {
471 41 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
472 41 : RIPEMD160Transform(context->state, context->buffer);
473 :
474 15670 : for (i = partLen; i + 63 < inputLen; i += 64) {
475 15629 : RIPEMD160Transform(context->state, &input[i]);
476 : }
477 :
478 41 : index = 0;
479 : } else {
480 49 : i = 0;
481 : }
482 :
483 : /* Buffer remaining input */
484 90 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
485 90 : }
486 : /* }}} */
487 :
488 : /* {{{ RIPEMD320Transform
489 : * ripemd320 basic transformation. Transforms state based on block.
490 : */
491 : static void RIPEMD320Transform(php_hash_uint32 state[10], const unsigned char block[64])
492 15654 : {
493 15654 : php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
494 15654 : 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 15654 : RIPEMDDecode(x, block, 64);
499 :
500 266118 : for(j = 0; j < 16; j++) {
501 250464 : tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
502 250464 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
503 250464 : tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
504 250464 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
505 : }
506 15654 : tmp = b; b = bb; bb = tmp;
507 :
508 266118 : for(j = 16; j < 32; j++) {
509 250464 : tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
510 250464 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
511 250464 : tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
512 250464 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
513 : }
514 15654 : tmp = d; d = dd; dd = tmp;
515 :
516 266118 : for(j = 32; j < 48; j++) {
517 250464 : tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
518 250464 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
519 250464 : tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
520 250464 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
521 : }
522 15654 : tmp = a; a = aa; aa = tmp;
523 :
524 266118 : for(j = 48; j < 64; j++) {
525 250464 : tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
526 250464 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
527 250464 : tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
528 250464 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
529 : }
530 15654 : tmp = c; c = cc; cc = tmp;
531 :
532 266118 : for(j = 64; j < 80; j++) {
533 250464 : tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
534 250464 : a = e; e = d; d = ROL(10, c); c = b; b = tmp;
535 250464 : tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
536 250464 : aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
537 : }
538 15654 : tmp = e; e = ee; ee = tmp;
539 :
540 15654 : state[0] += a;
541 15654 : state[1] += b;
542 15654 : state[2] += c;
543 15654 : state[3] += d;
544 15654 : state[4] += e;
545 15654 : state[5] += aa;
546 15654 : state[6] += bb;
547 15654 : state[7] += cc;
548 15654 : state[8] += dd;
549 15654 : state[9] += ee;
550 :
551 15654 : tmp = 0;
552 15654 : memset(x, 0, sizeof(x));
553 15654 : }
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 : */
561 : PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, unsigned int inputLen)
562 57 : {
563 : unsigned int i, index, partLen;
564 :
565 : /* Compute number of bytes mod 64 */
566 57 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
567 :
568 : /* Update number of bits */
569 57 : if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
570 0 : context->count[1]++;
571 : }
572 57 : context->count[1] += ((php_hash_uint32) inputLen >> 29);
573 :
574 57 : partLen = 64 - index;
575 :
576 : /* Transform as many times as possible.
577 : */
578 57 : if (inputLen >= partLen) {
579 30 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
580 30 : RIPEMD320Transform(context->state, context->buffer);
581 :
582 15654 : for (i = partLen; i + 63 < inputLen; i += 64) {
583 15624 : RIPEMD320Transform(context->state, &input[i]);
584 : }
585 :
586 30 : index = 0;
587 : } else {
588 27 : i = 0;
589 : }
590 :
591 : /* Buffer remaining input */
592 57 : memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
593 57 : }
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 : */
607 : static void RIPEMDEncode(unsigned char *output, php_hash_uint32 *input, unsigned int len)
608 78 : {
609 : unsigned int i, j;
610 :
611 594 : for (i = 0, j = 0; j < len; i++, j += 4) {
612 516 : output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
613 516 : output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
614 516 : output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
615 516 : output[j + 0] = (unsigned char) (input[i] & 0xff);
616 : }
617 78 : }
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 : */
624 : PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
625 18 : {
626 : unsigned char bits[8];
627 : unsigned int index, padLen;
628 :
629 : /* Save number of bits */
630 18 : bits[0] = (unsigned char) (context->count[0] & 0xFF);
631 18 : bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
632 18 : bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
633 18 : bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
634 18 : bits[4] = (unsigned char) (context->count[1] & 0xFF);
635 18 : bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
636 18 : bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
637 18 : bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
638 :
639 : /* Pad out to 56 mod 64.
640 : */
641 18 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
642 18 : padLen = (index < 56) ? (56 - index) : (120 - index);
643 18 : PHP_RIPEMD128Update(context, PADDING, padLen);
644 :
645 : /* Append length (before padding) */
646 18 : PHP_RIPEMD128Update(context, bits, 8);
647 :
648 : /* Store state in digest */
649 18 : RIPEMDEncode(digest, context->state, 16);
650 :
651 : /* Zeroize sensitive information.
652 : */
653 18 : memset((unsigned char*) context, 0, sizeof(*context));
654 18 : }
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 : */
661 : PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
662 18 : {
663 : unsigned char bits[8];
664 : unsigned int index, padLen;
665 :
666 : /* Save number of bits */
667 18 : bits[0] = (unsigned char) (context->count[0] & 0xFF);
668 18 : bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
669 18 : bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
670 18 : bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
671 18 : bits[4] = (unsigned char) (context->count[1] & 0xFF);
672 18 : bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
673 18 : bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
674 18 : bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
675 :
676 : /* Pad out to 56 mod 64.
677 : */
678 18 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
679 18 : padLen = (index < 56) ? (56 - index) : (120 - index);
680 18 : PHP_RIPEMD256Update(context, PADDING, padLen);
681 :
682 : /* Append length (before padding) */
683 18 : PHP_RIPEMD256Update(context, bits, 8);
684 :
685 : /* Store state in digest */
686 18 : RIPEMDEncode(digest, context->state, 32);
687 :
688 : /* Zeroize sensitive information.
689 : */
690 18 : memset((unsigned char*) context, 0, sizeof(*context));
691 18 : }
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 : */
698 : PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
699 24 : {
700 : unsigned char bits[8];
701 : unsigned int index, padLen;
702 :
703 : /* Save number of bits */
704 24 : bits[0] = (unsigned char) (context->count[0] & 0xFF);
705 24 : bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
706 24 : bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
707 24 : bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
708 24 : bits[4] = (unsigned char) (context->count[1] & 0xFF);
709 24 : bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
710 24 : bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
711 24 : bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
712 :
713 : /* Pad out to 56 mod 64.
714 : */
715 24 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
716 24 : padLen = (index < 56) ? (56 - index) : (120 - index);
717 24 : PHP_RIPEMD160Update(context, PADDING, padLen);
718 :
719 : /* Append length (before padding) */
720 24 : PHP_RIPEMD160Update(context, bits, 8);
721 :
722 : /* Store state in digest */
723 24 : RIPEMDEncode(digest, context->state, 20);
724 :
725 : /* Zeroize sensitive information.
726 : */
727 24 : memset((unsigned char*) context, 0, sizeof(*context));
728 24 : }
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 : */
735 : PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
736 18 : {
737 : unsigned char bits[8];
738 : unsigned int index, padLen;
739 :
740 : /* Save number of bits */
741 18 : bits[0] = (unsigned char) (context->count[0] & 0xFF);
742 18 : bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
743 18 : bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
744 18 : bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
745 18 : bits[4] = (unsigned char) (context->count[1] & 0xFF);
746 18 : bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
747 18 : bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
748 18 : bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
749 :
750 : /* Pad out to 56 mod 64.
751 : */
752 18 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
753 18 : padLen = (index < 56) ? (56 - index) : (120 - index);
754 18 : PHP_RIPEMD320Update(context, PADDING, padLen);
755 :
756 : /* Append length (before padding) */
757 18 : PHP_RIPEMD320Update(context, bits, 8);
758 :
759 : /* Store state in digest */
760 18 : RIPEMDEncode(digest, context->state, 40);
761 :
762 : /* Zeroize sensitive information.
763 : */
764 18 : memset((unsigned char*) context, 0, sizeof(*context));
765 18 : }
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 : */
|