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