blob: cdf85dbd2551bf3d8c6ca77654a9f6ec787a601f [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
4 * Copyright (C) 2014-2014, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26/*
27 * The RIPEMD-160 algorithm was designed by RIPE in 1996
28 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
29 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
30 */
31
32#include "polarssl/config.h"
33
34#if defined(POLARSSL_RMD160_C)
35
36#include "polarssl/rmd160.h"
37
38#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
39#include <stdio.h>
40#endif
41
42#if defined(POLARSSL_SELF_TEST)
43#include <string.h>
44#endif
45
46/*
47 * 32-bit integer manipulation macros (little endian)
48 */
49#ifndef GET_UINT32_LE
50#define GET_UINT32_LE(n,b,i) \
51{ \
52 (n) = ( (uint32_t) (b)[(i) ] ) \
53 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
54 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
55 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
56}
57#endif
58
59#ifndef PUT_UINT32_LE
60#define PUT_UINT32_LE(n,b,i) \
61{ \
62 (b)[(i) ] = (unsigned char) ( (n) ); \
63 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
64 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
65 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
66}
67#endif
68
69/*
70 * RMD160 context setup
71 */
72void rmd160_starts( rmd160_context *ctx )
73{
74 ctx->total[0] = 0;
75 ctx->total[1] = 0;
76
77 ctx->state[0] = 0x67452301;
78 ctx->state[1] = 0xEFCDAB89;
79 ctx->state[2] = 0x98BADCFE;
80 ctx->state[3] = 0x10325476;
81 ctx->state[4] = 0xC3D2E1F0;
82}
83
84void rmd160_process( rmd160_context *ctx, const unsigned char data[64] )
85{
86 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
87
88 GET_UINT32_LE( X[ 0], data, 0 );
89 GET_UINT32_LE( X[ 1], data, 4 );
90 GET_UINT32_LE( X[ 2], data, 8 );
91 GET_UINT32_LE( X[ 3], data, 12 );
92 GET_UINT32_LE( X[ 4], data, 16 );
93 GET_UINT32_LE( X[ 5], data, 20 );
94 GET_UINT32_LE( X[ 6], data, 24 );
95 GET_UINT32_LE( X[ 7], data, 28 );
96 GET_UINT32_LE( X[ 8], data, 32 );
97 GET_UINT32_LE( X[ 9], data, 36 );
98 GET_UINT32_LE( X[10], data, 40 );
99 GET_UINT32_LE( X[11], data, 44 );
100 GET_UINT32_LE( X[12], data, 48 );
101 GET_UINT32_LE( X[13], data, 52 );
102 GET_UINT32_LE( X[14], data, 56 );
103 GET_UINT32_LE( X[15], data, 60 );
104
105 A = Ap = ctx->state[0];
106 B = Bp = ctx->state[1];
107 C = Cp = ctx->state[2];
108 D = Dp = ctx->state[3];
109 E = Ep = ctx->state[4];
110
111#define F1( x, y, z ) ( x ^ y ^ z )
112#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
113#define F3( x, y, z ) ( ( x | ~y ) ^ z )
114#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
115#define F5( x, y, z ) ( x ^ ( y | ~z ) )
116
117#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
118
119#define P( a, b, c, d, e, r, s, f, k ) \
120 a += f( b, c, d ) + X[r] + k; \
121 a = S( a, s ) + e; \
122 c = S( c, 10 );
123
124#define P2( a, b, c, d, e, r, s, rp, sp ) \
125 P( a, b, c, d, e, r, s, F, K ); \
126 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
127
128#define F F1
129#define K 0x00000000
130#define Fp F5
131#define Kp 0x50A28BE6
132 P2( A, B, C, D, E, 0, 11, 5, 8 );
133 P2( E, A, B, C, D, 1, 14, 14, 9 );
134 P2( D, E, A, B, C, 2, 15, 7, 9 );
135 P2( C, D, E, A, B, 3, 12, 0, 11 );
136 P2( B, C, D, E, A, 4, 5, 9, 13 );
137 P2( A, B, C, D, E, 5, 8, 2, 15 );
138 P2( E, A, B, C, D, 6, 7, 11, 15 );
139 P2( D, E, A, B, C, 7, 9, 4, 5 );
140 P2( C, D, E, A, B, 8, 11, 13, 7 );
141 P2( B, C, D, E, A, 9, 13, 6, 7 );
142 P2( A, B, C, D, E, 10, 14, 15, 8 );
143 P2( E, A, B, C, D, 11, 15, 8, 11 );
144 P2( D, E, A, B, C, 12, 6, 1, 14 );
145 P2( C, D, E, A, B, 13, 7, 10, 14 );
146 P2( B, C, D, E, A, 14, 9, 3, 12 );
147 P2( A, B, C, D, E, 15, 8, 12, 6 );
148#undef F
149#undef K
150#undef Fp
151#undef Kp
152
153#define F F2
154#define K 0x5A827999
155#define Fp F4
156#define Kp 0x5C4DD124
157 P2( E, A, B, C, D, 7, 7, 6, 9 );
158 P2( D, E, A, B, C, 4, 6, 11, 13 );
159 P2( C, D, E, A, B, 13, 8, 3, 15 );
160 P2( B, C, D, E, A, 1, 13, 7, 7 );
161 P2( A, B, C, D, E, 10, 11, 0, 12 );
162 P2( E, A, B, C, D, 6, 9, 13, 8 );
163 P2( D, E, A, B, C, 15, 7, 5, 9 );
164 P2( C, D, E, A, B, 3, 15, 10, 11 );
165 P2( B, C, D, E, A, 12, 7, 14, 7 );
166 P2( A, B, C, D, E, 0, 12, 15, 7 );
167 P2( E, A, B, C, D, 9, 15, 8, 12 );
168 P2( D, E, A, B, C, 5, 9, 12, 7 );
169 P2( C, D, E, A, B, 2, 11, 4, 6 );
170 P2( B, C, D, E, A, 14, 7, 9, 15 );
171 P2( A, B, C, D, E, 11, 13, 1, 13 );
172 P2( E, A, B, C, D, 8, 12, 2, 11 );
173#undef F
174#undef K
175#undef Fp
176#undef Kp
177
178#define F F3
179#define K 0x6ED9EBA1
180#define Fp F3
181#define Kp 0x6D703EF3
182 P2( D, E, A, B, C, 3, 11, 15, 9 );
183 P2( C, D, E, A, B, 10, 13, 5, 7 );
184 P2( B, C, D, E, A, 14, 6, 1, 15 );
185 P2( A, B, C, D, E, 4, 7, 3, 11 );
186 P2( E, A, B, C, D, 9, 14, 7, 8 );
187 P2( D, E, A, B, C, 15, 9, 14, 6 );
188 P2( C, D, E, A, B, 8, 13, 6, 6 );
189 P2( B, C, D, E, A, 1, 15, 9, 14 );
190 P2( A, B, C, D, E, 2, 14, 11, 12 );
191 P2( E, A, B, C, D, 7, 8, 8, 13 );
192 P2( D, E, A, B, C, 0, 13, 12, 5 );
193 P2( C, D, E, A, B, 6, 6, 2, 14 );
194 P2( B, C, D, E, A, 13, 5, 10, 13 );
195 P2( A, B, C, D, E, 11, 12, 0, 13 );
196 P2( E, A, B, C, D, 5, 7, 4, 7 );
197 P2( D, E, A, B, C, 12, 5, 13, 5 );
198#undef F
199#undef K
200#undef Fp
201#undef Kp
202
203#define F F4
204#define K 0x8F1BBCDC
205#define Fp F2
206#define Kp 0x7A6D76E9
207 P2( C, D, E, A, B, 1, 11, 8, 15 );
208 P2( B, C, D, E, A, 9, 12, 6, 5 );
209 P2( A, B, C, D, E, 11, 14, 4, 8 );
210 P2( E, A, B, C, D, 10, 15, 1, 11 );
211 P2( D, E, A, B, C, 0, 14, 3, 14 );
212 P2( C, D, E, A, B, 8, 15, 11, 14 );
213 P2( B, C, D, E, A, 12, 9, 15, 6 );
214 P2( A, B, C, D, E, 4, 8, 0, 14 );
215 P2( E, A, B, C, D, 13, 9, 5, 6 );
216 P2( D, E, A, B, C, 3, 14, 12, 9 );
217 P2( C, D, E, A, B, 7, 5, 2, 12 );
218 P2( B, C, D, E, A, 15, 6, 13, 9 );
219 P2( A, B, C, D, E, 14, 8, 9, 12 );
220 P2( E, A, B, C, D, 5, 6, 7, 5 );
221 P2( D, E, A, B, C, 6, 5, 10, 15 );
222 P2( C, D, E, A, B, 2, 12, 14, 8 );
223#undef F
224#undef K
225#undef Fp
226#undef Kp
227
228#define F F5
229#define K 0xA953FD4E
230#define Fp F1
231#define Kp 0x00000000
232 P2( B, C, D, E, A, 4, 9, 12, 8 );
233 P2( A, B, C, D, E, 0, 15, 15, 5 );
234 P2( E, A, B, C, D, 5, 5, 10, 12 );
235 P2( D, E, A, B, C, 9, 11, 4, 9 );
236 P2( C, D, E, A, B, 7, 6, 1, 12 );
237 P2( B, C, D, E, A, 12, 8, 5, 5 );
238 P2( A, B, C, D, E, 2, 13, 8, 14 );
239 P2( E, A, B, C, D, 10, 12, 7, 6 );
240 P2( D, E, A, B, C, 14, 5, 6, 8 );
241 P2( C, D, E, A, B, 1, 12, 2, 13 );
242 P2( B, C, D, E, A, 3, 13, 13, 6 );
243 P2( A, B, C, D, E, 8, 14, 14, 5 );
244 P2( E, A, B, C, D, 11, 11, 0, 15 );
245 P2( D, E, A, B, C, 6, 8, 3, 13 );
246 P2( C, D, E, A, B, 15, 5, 9, 11 );
247 P2( B, C, D, E, A, 13, 6, 11, 11 );
248#undef F
249#undef K
250#undef Fp
251#undef Kp
252
253 C = ctx->state[1] + C + Dp;
254 ctx->state[1] = ctx->state[2] + D + Ep;
255 ctx->state[2] = ctx->state[3] + E + Ap;
256 ctx->state[3] = ctx->state[4] + A + Bp;
257 ctx->state[4] = ctx->state[0] + B + Cp;
258 ctx->state[0] = C;
259}
260
261/*
262 * RMD160 process buffer
263 */
264void rmd160_update( rmd160_context *ctx,
265 const unsigned char *input, size_t ilen )
266{
267 size_t fill;
268 uint32_t left;
269
270 if( ilen <= 0 )
271 return;
272
273 left = ctx->total[0] & 0x3F;
274 fill = 64 - left;
275
276 ctx->total[0] += (uint32_t) ilen;
277 ctx->total[0] &= 0xFFFFFFFF;
278
279 if( ctx->total[0] < (uint32_t) ilen )
280 ctx->total[1]++;
281
282 if( left && ilen >= fill )
283 {
284 memcpy( (void *) (ctx->buffer + left), input, fill );
285 rmd160_process( ctx, ctx->buffer );
286 input += fill;
287 ilen -= fill;
288 left = 0;
289 }
290
291 while( ilen >= 64 )
292 {
293 rmd160_process( ctx, input );
294 input += 64;
295 ilen -= 64;
296 }
297
298 if( ilen > 0 )
299 {
300 memcpy( (void *) (ctx->buffer + left), input, ilen );
301 }
302}
303
304static const unsigned char rmd160_padding[64] =
305{
306 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
310};
311
312/*
313 * RMD160 final digest
314 */
315void rmd160_finish( rmd160_context *ctx, unsigned char output[16] )
316{
317 uint32_t last, padn;
318 uint32_t high, low;
319 unsigned char msglen[8];
320
321 high = ( ctx->total[0] >> 29 )
322 | ( ctx->total[1] << 3 );
323 low = ( ctx->total[0] << 3 );
324
325 PUT_UINT32_LE( low, msglen, 0 );
326 PUT_UINT32_LE( high, msglen, 4 );
327
328 last = ctx->total[0] & 0x3F;
329 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
330
331 rmd160_update( ctx, rmd160_padding, padn );
332 rmd160_update( ctx, msglen, 8 );
333
334 PUT_UINT32_LE( ctx->state[0], output, 0 );
335 PUT_UINT32_LE( ctx->state[1], output, 4 );
336 PUT_UINT32_LE( ctx->state[2], output, 8 );
337 PUT_UINT32_LE( ctx->state[3], output, 12 );
338 PUT_UINT32_LE( ctx->state[4], output, 16 );
339}
340
341/*
342 * output = RMD160( input buffer )
343 */
344void rmd160( const unsigned char *input, size_t ilen, unsigned char output[16] )
345{
346 rmd160_context ctx;
347
348 rmd160_starts( &ctx );
349 rmd160_update( &ctx, input, ilen );
350 rmd160_finish( &ctx, output );
351
352 memset( &ctx, 0, sizeof( rmd160_context ) );
353}
354
355#if defined(POLARSSL_FS_IO)
356/*
357 * output = RMD160( file contents )
358 */
359int rmd160_file( const char *path, unsigned char output[16] )
360{
361 FILE *f;
362 size_t n;
363 rmd160_context ctx;
364 unsigned char buf[1024];
365
366 if( ( f = fopen( path, "rb" ) ) == NULL )
367 return( POLARSSL_ERR_RMD160_FILE_IO_ERROR );
368
369 rmd160_starts( &ctx );
370
371 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
372 rmd160_update( &ctx, buf, n );
373
374 rmd160_finish( &ctx, output );
375
376 memset( &ctx, 0, sizeof( rmd160_context ) );
377
378 if( ferror( f ) != 0 )
379 {
380 fclose( f );
381 return( POLARSSL_ERR_RMD160_FILE_IO_ERROR );
382 }
383
384 fclose( f );
385 return( 0 );
386}
387#endif /* POLARSSL_FS_IO */
388
389#if defined(POLARSSL_SELF_TEST)
390/*
391 * Test vectors from the RIPEMD-160 paper
392 */
393#define MD_TESTS 8
394static const char *rmd160_test_input[MD_TESTS] =
395{
396 "",
397 "a",
398 "abc",
399 "message digest",
400 "abcdefghijklmnopqrstuvwxyz",
401 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
402 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
403 "1234567890123456789012345678901234567890"
404 "1234567890123456789012345678901234567890",
405};
406
407static const unsigned char rmd160_test_output[MD_TESTS][20] =
408{
409 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
410 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
411 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
412 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
413 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
414 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
415 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
416 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
417 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
418 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
419 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
420 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
421 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
422 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
423 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
424 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
425};
426
427/*
428 * Checkup routine
429 */
430int rmd160_self_test( int verbose )
431{
432 int i;
433 unsigned char output[20];
434
435 memset( output, 0, sizeof output );
436
437 for( i = 0; i < MD_TESTS; i++ )
438 {
439 if( verbose != 0 )
440 printf( " RMD160 test #%d: ", i + 1 );
441
442 rmd160( (const unsigned char *)rmd160_test_input[i],
443 strlen( rmd160_test_input[i] ),
444 output );
445
446 if( memcmp( output, rmd160_test_output[i], 20 ) != 0 )
447 {
448 if( verbose != 0 )
449 printf( "failed\n" );
450
451 return( 1 );
452 }
453
454 if( verbose != 0 )
455 printf( "passed\n" );
456 }
457
458 if( verbose != 0 )
459 printf( "\n" );
460
461 return( 0 );
462}
463
464#endif
465
466#endif