xref: /PHP-7.2/ext/hash/hash_ripemd.c (revision 7a7ec01a)
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