blob: 12c2e20cdcfcccbbbaa7173380bb132d92b87bdc [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2014-2014, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01007 *
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23/*
24 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020025 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010026 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
27 */
28
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020033#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010034
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010036
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/ripemd160.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010042#include <stdio.h>
43#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_SELF_TEST)
46#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#define mbedtls_printf printf
51#endif /* MBEDTLS_PLATFORM_C */
52#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010054/*
55 * 32-bit integer manipulation macros (little endian)
56 */
57#ifndef GET_UINT32_LE
58#define GET_UINT32_LE(n,b,i) \
59{ \
60 (n) = ( (uint32_t) (b)[(i) ] ) \
61 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
62 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
63 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
64}
65#endif
66
67#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000068#define PUT_UINT32_LE(n,b,i) \
69{ \
70 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
71 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
72 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
73 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010074}
75#endif
76
Paul Bakker34617722014-06-13 17:20:13 +020077/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020079 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
80}
81
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020083{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020085}
86
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020088{
89 if( ctx == NULL )
90 return;
91
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020092 mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020093}
94
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010095/*
Paul Bakker61b699e2014-01-22 13:35:29 +010096 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010097 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020098void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010099{
100 ctx->total[0] = 0;
101 ctx->total[1] = 0;
102
103 ctx->state[0] = 0x67452301;
104 ctx->state[1] = 0xEFCDAB89;
105 ctx->state[2] = 0x98BADCFE;
106 ctx->state[3] = 0x10325476;
107 ctx->state[4] = 0xC3D2E1F0;
108}
109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100111/*
112 * Process one block
113 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100115{
116 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
117
118 GET_UINT32_LE( X[ 0], data, 0 );
119 GET_UINT32_LE( X[ 1], data, 4 );
120 GET_UINT32_LE( X[ 2], data, 8 );
121 GET_UINT32_LE( X[ 3], data, 12 );
122 GET_UINT32_LE( X[ 4], data, 16 );
123 GET_UINT32_LE( X[ 5], data, 20 );
124 GET_UINT32_LE( X[ 6], data, 24 );
125 GET_UINT32_LE( X[ 7], data, 28 );
126 GET_UINT32_LE( X[ 8], data, 32 );
127 GET_UINT32_LE( X[ 9], data, 36 );
128 GET_UINT32_LE( X[10], data, 40 );
129 GET_UINT32_LE( X[11], data, 44 );
130 GET_UINT32_LE( X[12], data, 48 );
131 GET_UINT32_LE( X[13], data, 52 );
132 GET_UINT32_LE( X[14], data, 56 );
133 GET_UINT32_LE( X[15], data, 60 );
134
135 A = Ap = ctx->state[0];
136 B = Bp = ctx->state[1];
137 C = Cp = ctx->state[2];
138 D = Dp = ctx->state[3];
139 E = Ep = ctx->state[4];
140
141#define F1( x, y, z ) ( x ^ y ^ z )
142#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
143#define F3( x, y, z ) ( ( x | ~y ) ^ z )
144#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
145#define F5( x, y, z ) ( x ^ ( y | ~z ) )
146
147#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
148
149#define P( a, b, c, d, e, r, s, f, k ) \
150 a += f( b, c, d ) + X[r] + k; \
151 a = S( a, s ) + e; \
152 c = S( c, 10 );
153
154#define P2( a, b, c, d, e, r, s, rp, sp ) \
155 P( a, b, c, d, e, r, s, F, K ); \
156 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
157
158#define F F1
159#define K 0x00000000
160#define Fp F5
161#define Kp 0x50A28BE6
162 P2( A, B, C, D, E, 0, 11, 5, 8 );
163 P2( E, A, B, C, D, 1, 14, 14, 9 );
164 P2( D, E, A, B, C, 2, 15, 7, 9 );
165 P2( C, D, E, A, B, 3, 12, 0, 11 );
166 P2( B, C, D, E, A, 4, 5, 9, 13 );
167 P2( A, B, C, D, E, 5, 8, 2, 15 );
168 P2( E, A, B, C, D, 6, 7, 11, 15 );
169 P2( D, E, A, B, C, 7, 9, 4, 5 );
170 P2( C, D, E, A, B, 8, 11, 13, 7 );
171 P2( B, C, D, E, A, 9, 13, 6, 7 );
172 P2( A, B, C, D, E, 10, 14, 15, 8 );
173 P2( E, A, B, C, D, 11, 15, 8, 11 );
174 P2( D, E, A, B, C, 12, 6, 1, 14 );
175 P2( C, D, E, A, B, 13, 7, 10, 14 );
176 P2( B, C, D, E, A, 14, 9, 3, 12 );
177 P2( A, B, C, D, E, 15, 8, 12, 6 );
178#undef F
179#undef K
180#undef Fp
181#undef Kp
182
183#define F F2
184#define K 0x5A827999
185#define Fp F4
186#define Kp 0x5C4DD124
187 P2( E, A, B, C, D, 7, 7, 6, 9 );
188 P2( D, E, A, B, C, 4, 6, 11, 13 );
189 P2( C, D, E, A, B, 13, 8, 3, 15 );
190 P2( B, C, D, E, A, 1, 13, 7, 7 );
191 P2( A, B, C, D, E, 10, 11, 0, 12 );
192 P2( E, A, B, C, D, 6, 9, 13, 8 );
193 P2( D, E, A, B, C, 15, 7, 5, 9 );
194 P2( C, D, E, A, B, 3, 15, 10, 11 );
195 P2( B, C, D, E, A, 12, 7, 14, 7 );
196 P2( A, B, C, D, E, 0, 12, 15, 7 );
197 P2( E, A, B, C, D, 9, 15, 8, 12 );
198 P2( D, E, A, B, C, 5, 9, 12, 7 );
199 P2( C, D, E, A, B, 2, 11, 4, 6 );
200 P2( B, C, D, E, A, 14, 7, 9, 15 );
201 P2( A, B, C, D, E, 11, 13, 1, 13 );
202 P2( E, A, B, C, D, 8, 12, 2, 11 );
203#undef F
204#undef K
205#undef Fp
206#undef Kp
207
208#define F F3
209#define K 0x6ED9EBA1
210#define Fp F3
211#define Kp 0x6D703EF3
212 P2( D, E, A, B, C, 3, 11, 15, 9 );
213 P2( C, D, E, A, B, 10, 13, 5, 7 );
214 P2( B, C, D, E, A, 14, 6, 1, 15 );
215 P2( A, B, C, D, E, 4, 7, 3, 11 );
216 P2( E, A, B, C, D, 9, 14, 7, 8 );
217 P2( D, E, A, B, C, 15, 9, 14, 6 );
218 P2( C, D, E, A, B, 8, 13, 6, 6 );
219 P2( B, C, D, E, A, 1, 15, 9, 14 );
220 P2( A, B, C, D, E, 2, 14, 11, 12 );
221 P2( E, A, B, C, D, 7, 8, 8, 13 );
222 P2( D, E, A, B, C, 0, 13, 12, 5 );
223 P2( C, D, E, A, B, 6, 6, 2, 14 );
224 P2( B, C, D, E, A, 13, 5, 10, 13 );
225 P2( A, B, C, D, E, 11, 12, 0, 13 );
226 P2( E, A, B, C, D, 5, 7, 4, 7 );
227 P2( D, E, A, B, C, 12, 5, 13, 5 );
228#undef F
229#undef K
230#undef Fp
231#undef Kp
232
233#define F F4
234#define K 0x8F1BBCDC
235#define Fp F2
236#define Kp 0x7A6D76E9
237 P2( C, D, E, A, B, 1, 11, 8, 15 );
238 P2( B, C, D, E, A, 9, 12, 6, 5 );
239 P2( A, B, C, D, E, 11, 14, 4, 8 );
240 P2( E, A, B, C, D, 10, 15, 1, 11 );
241 P2( D, E, A, B, C, 0, 14, 3, 14 );
242 P2( C, D, E, A, B, 8, 15, 11, 14 );
243 P2( B, C, D, E, A, 12, 9, 15, 6 );
244 P2( A, B, C, D, E, 4, 8, 0, 14 );
245 P2( E, A, B, C, D, 13, 9, 5, 6 );
246 P2( D, E, A, B, C, 3, 14, 12, 9 );
247 P2( C, D, E, A, B, 7, 5, 2, 12 );
248 P2( B, C, D, E, A, 15, 6, 13, 9 );
249 P2( A, B, C, D, E, 14, 8, 9, 12 );
250 P2( E, A, B, C, D, 5, 6, 7, 5 );
251 P2( D, E, A, B, C, 6, 5, 10, 15 );
252 P2( C, D, E, A, B, 2, 12, 14, 8 );
253#undef F
254#undef K
255#undef Fp
256#undef Kp
257
258#define F F5
259#define K 0xA953FD4E
260#define Fp F1
261#define Kp 0x00000000
262 P2( B, C, D, E, A, 4, 9, 12, 8 );
263 P2( A, B, C, D, E, 0, 15, 15, 5 );
264 P2( E, A, B, C, D, 5, 5, 10, 12 );
265 P2( D, E, A, B, C, 9, 11, 4, 9 );
266 P2( C, D, E, A, B, 7, 6, 1, 12 );
267 P2( B, C, D, E, A, 12, 8, 5, 5 );
268 P2( A, B, C, D, E, 2, 13, 8, 14 );
269 P2( E, A, B, C, D, 10, 12, 7, 6 );
270 P2( D, E, A, B, C, 14, 5, 6, 8 );
271 P2( C, D, E, A, B, 1, 12, 2, 13 );
272 P2( B, C, D, E, A, 3, 13, 13, 6 );
273 P2( A, B, C, D, E, 8, 14, 14, 5 );
274 P2( E, A, B, C, D, 11, 11, 0, 15 );
275 P2( D, E, A, B, C, 6, 8, 3, 13 );
276 P2( C, D, E, A, B, 15, 5, 9, 11 );
277 P2( B, C, D, E, A, 13, 6, 11, 11 );
278#undef F
279#undef K
280#undef Fp
281#undef Kp
282
283 C = ctx->state[1] + C + Dp;
284 ctx->state[1] = ctx->state[2] + D + Ep;
285 ctx->state[2] = ctx->state[3] + E + Ap;
286 ctx->state[3] = ctx->state[4] + A + Bp;
287 ctx->state[4] = ctx->state[0] + B + Cp;
288 ctx->state[0] = C;
289}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200290#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100291
292/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100293 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100294 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
Paul Bakker61b699e2014-01-22 13:35:29 +0100296 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297{
298 size_t fill;
299 uint32_t left;
300
Brian White12895d12014-04-11 11:29:42 -0400301 if( ilen == 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100302 return;
303
304 left = ctx->total[0] & 0x3F;
305 fill = 64 - left;
306
307 ctx->total[0] += (uint32_t) ilen;
308 ctx->total[0] &= 0xFFFFFFFF;
309
310 if( ctx->total[0] < (uint32_t) ilen )
311 ctx->total[1]++;
312
313 if( left && ilen >= fill )
314 {
315 memcpy( (void *) (ctx->buffer + left), input, fill );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316 mbedtls_ripemd160_process( ctx, ctx->buffer );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100317 input += fill;
318 ilen -= fill;
319 left = 0;
320 }
321
322 while( ilen >= 64 )
323 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324 mbedtls_ripemd160_process( ctx, input );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100325 input += 64;
326 ilen -= 64;
327 }
328
329 if( ilen > 0 )
330 {
331 memcpy( (void *) (ctx->buffer + left), input, ilen );
332 }
333}
334
Paul Bakker61b699e2014-01-22 13:35:29 +0100335static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100336{
337 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
339 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
341};
342
343/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100344 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100345 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100347{
348 uint32_t last, padn;
349 uint32_t high, low;
350 unsigned char msglen[8];
351
352 high = ( ctx->total[0] >> 29 )
353 | ( ctx->total[1] << 3 );
354 low = ( ctx->total[0] << 3 );
355
356 PUT_UINT32_LE( low, msglen, 0 );
357 PUT_UINT32_LE( high, msglen, 4 );
358
359 last = ctx->total[0] & 0x3F;
360 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
363 mbedtls_ripemd160_update( ctx, msglen, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364
365 PUT_UINT32_LE( ctx->state[0], output, 0 );
366 PUT_UINT32_LE( ctx->state[1], output, 4 );
367 PUT_UINT32_LE( ctx->state[2], output, 8 );
368 PUT_UINT32_LE( ctx->state[3], output, 12 );
369 PUT_UINT32_LE( ctx->state[4], output, 16 );
370}
371
372/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100373 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100374 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375void mbedtls_ripemd160( const unsigned char *input, size_t ilen,
Paul Bakker61b699e2014-01-22 13:35:29 +0100376 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100377{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100379
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380 mbedtls_ripemd160_init( &ctx );
381 mbedtls_ripemd160_starts( &ctx );
382 mbedtls_ripemd160_update( &ctx, input, ilen );
383 mbedtls_ripemd160_finish( &ctx, output );
384 mbedtls_ripemd160_free( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100385}
386
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100388/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100389 * output = RIPEMD-160( file contents )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100390 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391int mbedtls_ripemd160_file( const char *path, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100392{
393 FILE *f;
394 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100396 unsigned char buf[1024];
397
398 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399 return( MBEDTLS_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100400
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 mbedtls_ripemd160_init( &ctx );
402 mbedtls_ripemd160_starts( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100403
404 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_ripemd160_update( &ctx, buf, n );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407 mbedtls_ripemd160_finish( &ctx, output );
408 mbedtls_ripemd160_free( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100409
410 if( ferror( f ) != 0 )
411 {
412 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 return( MBEDTLS_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100414 }
415
416 fclose( f );
417 return( 0 );
418}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100422/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100423 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100425 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100426#define TESTS 8
427#define KEYS 2
Paul Bakker61b699e2014-01-22 13:35:29 +0100428static const char *ripemd160_test_input[TESTS] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100429{
430 "",
431 "a",
432 "abc",
433 "message digest",
434 "abcdefghijklmnopqrstuvwxyz",
435 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
436 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
437 "1234567890123456789012345678901234567890"
438 "1234567890123456789012345678901234567890",
439};
440
Paul Bakker61b699e2014-01-22 13:35:29 +0100441static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100442{
443 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
444 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
445 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
446 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
447 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
448 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
449 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
450 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
451 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
452 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
453 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
454 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
455 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
456 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
457 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
458 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
459};
460
461/*
462 * Checkup routine
463 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100465{
Manuel Pégourié-Gonnard4da88c52015-03-24 18:23:20 +0100466 int i;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100467 unsigned char output[20];
468
469 memset( output, 0, sizeof output );
470
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100471 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100472 {
473 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 mbedtls_ripemd160( (const unsigned char *) ripemd160_test_input[i],
Paul Bakker61b699e2014-01-22 13:35:29 +0100477 strlen( ripemd160_test_input[i] ),
478 output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100479
Paul Bakker61b699e2014-01-22 13:35:29 +0100480 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100481 {
482 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483 mbedtls_printf( "failed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100484
485 return( 1 );
486 }
487
488 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100490 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100491
492 return( 0 );
493}
494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497#endif /* MBEDTLS_RIPEMD160_C */