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