blob: 768e2659ed2acc754ca858ce1a9fd6283ef13e9e [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é-Gonnard860b5162015-01-28 17:12:07 +00006 * This file is part of mbed TLS (https://polarssl.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
25 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
26 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
27 */
28
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020029#if !defined(POLARSSL_CONFIG_FILE)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010030#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#else
32#include POLARSSL_CONFIG_FILE
33#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010034
Paul Bakker61b699e2014-01-22 13:35:29 +010035#if defined(POLARSSL_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010036
Paul Bakker61b699e2014-01-22 13:35:29 +010037#include "polarssl/ripemd160.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010038
39#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
40#include <stdio.h>
41#endif
42
43#if defined(POLARSSL_SELF_TEST)
44#include <string.h>
45#endif
46
Paul Bakker7dc4c442014-02-01 22:50:26 +010047#if defined(POLARSSL_PLATFORM_C)
48#include "polarssl/platform.h"
49#else
50#define polarssl_printf printf
51#endif
52
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010053/*
54 * 32-bit integer manipulation macros (little endian)
55 */
56#ifndef GET_UINT32_LE
57#define GET_UINT32_LE(n,b,i) \
58{ \
59 (n) = ( (uint32_t) (b)[(i) ] ) \
60 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
61 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
62 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
63}
64#endif
65
66#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000067#define PUT_UINT32_LE(n,b,i) \
68{ \
69 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
70 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
71 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
72 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010073}
74#endif
75
Paul Bakker34617722014-06-13 17:20:13 +020076/* Implementation that should never be optimized out by the compiler */
77static void polarssl_zeroize( void *v, size_t n ) {
78 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
79}
80
Paul Bakker5b4af392014-06-26 12:09:34 +020081void ripemd160_init( ripemd160_context *ctx )
82{
83 memset( ctx, 0, sizeof( ripemd160_context ) );
84}
85
86void ripemd160_free( ripemd160_context *ctx )
87{
88 if( ctx == NULL )
89 return;
90
91 polarssl_zeroize( ctx, sizeof( ripemd160_context ) );
92}
93
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010094/*
Paul Bakker61b699e2014-01-22 13:35:29 +010095 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010096 */
Paul Bakker61b699e2014-01-22 13:35:29 +010097void ripemd160_starts( ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010098{
99 ctx->total[0] = 0;
100 ctx->total[1] = 0;
101
102 ctx->state[0] = 0x67452301;
103 ctx->state[1] = 0xEFCDAB89;
104 ctx->state[2] = 0x98BADCFE;
105 ctx->state[3] = 0x10325476;
106 ctx->state[4] = 0xC3D2E1F0;
107}
108
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100109/*
110 * Process one block
111 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100112void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100113{
114 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
115
116 GET_UINT32_LE( X[ 0], data, 0 );
117 GET_UINT32_LE( X[ 1], data, 4 );
118 GET_UINT32_LE( X[ 2], data, 8 );
119 GET_UINT32_LE( X[ 3], data, 12 );
120 GET_UINT32_LE( X[ 4], data, 16 );
121 GET_UINT32_LE( X[ 5], data, 20 );
122 GET_UINT32_LE( X[ 6], data, 24 );
123 GET_UINT32_LE( X[ 7], data, 28 );
124 GET_UINT32_LE( X[ 8], data, 32 );
125 GET_UINT32_LE( X[ 9], data, 36 );
126 GET_UINT32_LE( X[10], data, 40 );
127 GET_UINT32_LE( X[11], data, 44 );
128 GET_UINT32_LE( X[12], data, 48 );
129 GET_UINT32_LE( X[13], data, 52 );
130 GET_UINT32_LE( X[14], data, 56 );
131 GET_UINT32_LE( X[15], data, 60 );
132
133 A = Ap = ctx->state[0];
134 B = Bp = ctx->state[1];
135 C = Cp = ctx->state[2];
136 D = Dp = ctx->state[3];
137 E = Ep = ctx->state[4];
138
139#define F1( x, y, z ) ( x ^ y ^ z )
140#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
141#define F3( x, y, z ) ( ( x | ~y ) ^ z )
142#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
143#define F5( x, y, z ) ( x ^ ( y | ~z ) )
144
145#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
146
147#define P( a, b, c, d, e, r, s, f, k ) \
148 a += f( b, c, d ) + X[r] + k; \
149 a = S( a, s ) + e; \
150 c = S( c, 10 );
151
152#define P2( a, b, c, d, e, r, s, rp, sp ) \
153 P( a, b, c, d, e, r, s, F, K ); \
154 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
155
156#define F F1
157#define K 0x00000000
158#define Fp F5
159#define Kp 0x50A28BE6
160 P2( A, B, C, D, E, 0, 11, 5, 8 );
161 P2( E, A, B, C, D, 1, 14, 14, 9 );
162 P2( D, E, A, B, C, 2, 15, 7, 9 );
163 P2( C, D, E, A, B, 3, 12, 0, 11 );
164 P2( B, C, D, E, A, 4, 5, 9, 13 );
165 P2( A, B, C, D, E, 5, 8, 2, 15 );
166 P2( E, A, B, C, D, 6, 7, 11, 15 );
167 P2( D, E, A, B, C, 7, 9, 4, 5 );
168 P2( C, D, E, A, B, 8, 11, 13, 7 );
169 P2( B, C, D, E, A, 9, 13, 6, 7 );
170 P2( A, B, C, D, E, 10, 14, 15, 8 );
171 P2( E, A, B, C, D, 11, 15, 8, 11 );
172 P2( D, E, A, B, C, 12, 6, 1, 14 );
173 P2( C, D, E, A, B, 13, 7, 10, 14 );
174 P2( B, C, D, E, A, 14, 9, 3, 12 );
175 P2( A, B, C, D, E, 15, 8, 12, 6 );
176#undef F
177#undef K
178#undef Fp
179#undef Kp
180
181#define F F2
182#define K 0x5A827999
183#define Fp F4
184#define Kp 0x5C4DD124
185 P2( E, A, B, C, D, 7, 7, 6, 9 );
186 P2( D, E, A, B, C, 4, 6, 11, 13 );
187 P2( C, D, E, A, B, 13, 8, 3, 15 );
188 P2( B, C, D, E, A, 1, 13, 7, 7 );
189 P2( A, B, C, D, E, 10, 11, 0, 12 );
190 P2( E, A, B, C, D, 6, 9, 13, 8 );
191 P2( D, E, A, B, C, 15, 7, 5, 9 );
192 P2( C, D, E, A, B, 3, 15, 10, 11 );
193 P2( B, C, D, E, A, 12, 7, 14, 7 );
194 P2( A, B, C, D, E, 0, 12, 15, 7 );
195 P2( E, A, B, C, D, 9, 15, 8, 12 );
196 P2( D, E, A, B, C, 5, 9, 12, 7 );
197 P2( C, D, E, A, B, 2, 11, 4, 6 );
198 P2( B, C, D, E, A, 14, 7, 9, 15 );
199 P2( A, B, C, D, E, 11, 13, 1, 13 );
200 P2( E, A, B, C, D, 8, 12, 2, 11 );
201#undef F
202#undef K
203#undef Fp
204#undef Kp
205
206#define F F3
207#define K 0x6ED9EBA1
208#define Fp F3
209#define Kp 0x6D703EF3
210 P2( D, E, A, B, C, 3, 11, 15, 9 );
211 P2( C, D, E, A, B, 10, 13, 5, 7 );
212 P2( B, C, D, E, A, 14, 6, 1, 15 );
213 P2( A, B, C, D, E, 4, 7, 3, 11 );
214 P2( E, A, B, C, D, 9, 14, 7, 8 );
215 P2( D, E, A, B, C, 15, 9, 14, 6 );
216 P2( C, D, E, A, B, 8, 13, 6, 6 );
217 P2( B, C, D, E, A, 1, 15, 9, 14 );
218 P2( A, B, C, D, E, 2, 14, 11, 12 );
219 P2( E, A, B, C, D, 7, 8, 8, 13 );
220 P2( D, E, A, B, C, 0, 13, 12, 5 );
221 P2( C, D, E, A, B, 6, 6, 2, 14 );
222 P2( B, C, D, E, A, 13, 5, 10, 13 );
223 P2( A, B, C, D, E, 11, 12, 0, 13 );
224 P2( E, A, B, C, D, 5, 7, 4, 7 );
225 P2( D, E, A, B, C, 12, 5, 13, 5 );
226#undef F
227#undef K
228#undef Fp
229#undef Kp
230
231#define F F4
232#define K 0x8F1BBCDC
233#define Fp F2
234#define Kp 0x7A6D76E9
235 P2( C, D, E, A, B, 1, 11, 8, 15 );
236 P2( B, C, D, E, A, 9, 12, 6, 5 );
237 P2( A, B, C, D, E, 11, 14, 4, 8 );
238 P2( E, A, B, C, D, 10, 15, 1, 11 );
239 P2( D, E, A, B, C, 0, 14, 3, 14 );
240 P2( C, D, E, A, B, 8, 15, 11, 14 );
241 P2( B, C, D, E, A, 12, 9, 15, 6 );
242 P2( A, B, C, D, E, 4, 8, 0, 14 );
243 P2( E, A, B, C, D, 13, 9, 5, 6 );
244 P2( D, E, A, B, C, 3, 14, 12, 9 );
245 P2( C, D, E, A, B, 7, 5, 2, 12 );
246 P2( B, C, D, E, A, 15, 6, 13, 9 );
247 P2( A, B, C, D, E, 14, 8, 9, 12 );
248 P2( E, A, B, C, D, 5, 6, 7, 5 );
249 P2( D, E, A, B, C, 6, 5, 10, 15 );
250 P2( C, D, E, A, B, 2, 12, 14, 8 );
251#undef F
252#undef K
253#undef Fp
254#undef Kp
255
256#define F F5
257#define K 0xA953FD4E
258#define Fp F1
259#define Kp 0x00000000
260 P2( B, C, D, E, A, 4, 9, 12, 8 );
261 P2( A, B, C, D, E, 0, 15, 15, 5 );
262 P2( E, A, B, C, D, 5, 5, 10, 12 );
263 P2( D, E, A, B, C, 9, 11, 4, 9 );
264 P2( C, D, E, A, B, 7, 6, 1, 12 );
265 P2( B, C, D, E, A, 12, 8, 5, 5 );
266 P2( A, B, C, D, E, 2, 13, 8, 14 );
267 P2( E, A, B, C, D, 10, 12, 7, 6 );
268 P2( D, E, A, B, C, 14, 5, 6, 8 );
269 P2( C, D, E, A, B, 1, 12, 2, 13 );
270 P2( B, C, D, E, A, 3, 13, 13, 6 );
271 P2( A, B, C, D, E, 8, 14, 14, 5 );
272 P2( E, A, B, C, D, 11, 11, 0, 15 );
273 P2( D, E, A, B, C, 6, 8, 3, 13 );
274 P2( C, D, E, A, B, 15, 5, 9, 11 );
275 P2( B, C, D, E, A, 13, 6, 11, 11 );
276#undef F
277#undef K
278#undef Fp
279#undef Kp
280
281 C = ctx->state[1] + C + Dp;
282 ctx->state[1] = ctx->state[2] + D + Ep;
283 ctx->state[2] = ctx->state[3] + E + Ap;
284 ctx->state[3] = ctx->state[4] + A + Bp;
285 ctx->state[4] = ctx->state[0] + B + Cp;
286 ctx->state[0] = C;
287}
288
289/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100290 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100291 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100292void ripemd160_update( ripemd160_context *ctx,
293 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100294{
295 size_t fill;
296 uint32_t left;
297
Brian White12895d12014-04-11 11:29:42 -0400298 if( ilen == 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100299 return;
300
301 left = ctx->total[0] & 0x3F;
302 fill = 64 - left;
303
304 ctx->total[0] += (uint32_t) ilen;
305 ctx->total[0] &= 0xFFFFFFFF;
306
307 if( ctx->total[0] < (uint32_t) ilen )
308 ctx->total[1]++;
309
310 if( left && ilen >= fill )
311 {
312 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker61b699e2014-01-22 13:35:29 +0100313 ripemd160_process( ctx, ctx->buffer );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100314 input += fill;
315 ilen -= fill;
316 left = 0;
317 }
318
319 while( ilen >= 64 )
320 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100321 ripemd160_process( ctx, input );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100322 input += 64;
323 ilen -= 64;
324 }
325
326 if( ilen > 0 )
327 {
328 memcpy( (void *) (ctx->buffer + left), input, ilen );
329 }
330}
331
Paul Bakker61b699e2014-01-22 13:35:29 +0100332static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100333{
334 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
338};
339
340/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100341 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100342 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100343void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100344{
345 uint32_t last, padn;
346 uint32_t high, low;
347 unsigned char msglen[8];
348
349 high = ( ctx->total[0] >> 29 )
350 | ( ctx->total[1] << 3 );
351 low = ( ctx->total[0] << 3 );
352
353 PUT_UINT32_LE( low, msglen, 0 );
354 PUT_UINT32_LE( high, msglen, 4 );
355
356 last = ctx->total[0] & 0x3F;
357 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
358
Paul Bakker61b699e2014-01-22 13:35:29 +0100359 ripemd160_update( ctx, ripemd160_padding, padn );
360 ripemd160_update( ctx, msglen, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361
362 PUT_UINT32_LE( ctx->state[0], output, 0 );
363 PUT_UINT32_LE( ctx->state[1], output, 4 );
364 PUT_UINT32_LE( ctx->state[2], output, 8 );
365 PUT_UINT32_LE( ctx->state[3], output, 12 );
366 PUT_UINT32_LE( ctx->state[4], output, 16 );
367}
368
369/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100370 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100371 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100372void ripemd160( const unsigned char *input, size_t ilen,
373 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100374{
Paul Bakker61b699e2014-01-22 13:35:29 +0100375 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100376
Paul Bakker5b4af392014-06-26 12:09:34 +0200377 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100378 ripemd160_starts( &ctx );
379 ripemd160_update( &ctx, input, ilen );
380 ripemd160_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200381 ripemd160_free( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100382}
383
384#if defined(POLARSSL_FS_IO)
385/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100386 * output = RIPEMD-160( file contents )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100387 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100388int ripemd160_file( const char *path, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100389{
390 FILE *f;
391 size_t n;
Paul Bakker61b699e2014-01-22 13:35:29 +0100392 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100393 unsigned char buf[1024];
394
395 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker61b699e2014-01-22 13:35:29 +0100396 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100397
Paul Bakker5b4af392014-06-26 12:09:34 +0200398 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100399 ripemd160_starts( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100400
401 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100402 ripemd160_update( &ctx, buf, n );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100403
Paul Bakker61b699e2014-01-22 13:35:29 +0100404 ripemd160_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200405 ripemd160_free( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406
407 if( ferror( f ) != 0 )
408 {
409 fclose( f );
Paul Bakker61b699e2014-01-22 13:35:29 +0100410 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100411 }
412
413 fclose( f );
414 return( 0 );
415}
416#endif /* POLARSSL_FS_IO */
417
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100418/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100419 * RIPEMD-160 HMAC context setup
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100420 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100421void ripemd160_hmac_starts( ripemd160_context *ctx,
422 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100423{
424 size_t i;
425 unsigned char sum[20];
426
427 if( keylen > 64 )
428 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100429 ripemd160( key, keylen, sum );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100430 keylen = 20;
431 key = sum;
432 }
433
434 memset( ctx->ipad, 0x36, 64 );
435 memset( ctx->opad, 0x5C, 64 );
436
437 for( i = 0; i < keylen; i++ )
438 {
439 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
440 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
441 }
442
Paul Bakker61b699e2014-01-22 13:35:29 +0100443 ripemd160_starts( ctx );
444 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100445
Paul Bakker34617722014-06-13 17:20:13 +0200446 polarssl_zeroize( sum, sizeof( sum ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100447}
448
449/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100450 * RIPEMD-160 HMAC process buffer
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100451 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100452void ripemd160_hmac_update( ripemd160_context *ctx,
453 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100454{
Paul Bakker61b699e2014-01-22 13:35:29 +0100455 ripemd160_update( ctx, input, ilen );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100456}
457
458/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100459 * RIPEMD-160 HMAC final digest
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100460 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100461void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100462{
463 unsigned char tmpbuf[20];
464
Paul Bakker61b699e2014-01-22 13:35:29 +0100465 ripemd160_finish( ctx, tmpbuf );
466 ripemd160_starts( ctx );
467 ripemd160_update( ctx, ctx->opad, 64 );
468 ripemd160_update( ctx, tmpbuf, 20 );
469 ripemd160_finish( ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100470
Paul Bakker34617722014-06-13 17:20:13 +0200471 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100472}
473
474/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100475 * RIPEMD-160 HMAC context reset
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100476 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100477void ripemd160_hmac_reset( ripemd160_context *ctx )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100478{
Paul Bakker61b699e2014-01-22 13:35:29 +0100479 ripemd160_starts( ctx );
480 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100481}
482
483/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100484 * output = HMAC-RIPEMD-160( hmac key, input buffer )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100485 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100486void ripemd160_hmac( const unsigned char *key, size_t keylen,
487 const unsigned char *input, size_t ilen,
488 unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100489{
Paul Bakker61b699e2014-01-22 13:35:29 +0100490 ripemd160_context ctx;
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100491
Paul Bakker5b4af392014-06-26 12:09:34 +0200492 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100493 ripemd160_hmac_starts( &ctx, key, keylen );
494 ripemd160_hmac_update( &ctx, input, ilen );
495 ripemd160_hmac_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200496 ripemd160_free( &ctx );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100497}
498
499
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100500#if defined(POLARSSL_SELF_TEST)
501/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100502 * Test vectors from the RIPEMD-160 paper and
503 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100504 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100505#define TESTS 8
506#define KEYS 2
Paul Bakker61b699e2014-01-22 13:35:29 +0100507static const char *ripemd160_test_input[TESTS] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100508{
509 "",
510 "a",
511 "abc",
512 "message digest",
513 "abcdefghijklmnopqrstuvwxyz",
514 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
515 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
516 "1234567890123456789012345678901234567890"
517 "1234567890123456789012345678901234567890",
518};
519
Paul Bakker61b699e2014-01-22 13:35:29 +0100520static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100521{
522 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
523 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
524 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
525 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
526 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
527 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
528 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
529 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
530 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
531 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
532 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
533 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
534 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
535 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
536 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
537 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
538};
539
Paul Bakker61b699e2014-01-22 13:35:29 +0100540static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100541{
542 {
543 { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b,
544 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 },
545 { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39,
546 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc },
547 { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7,
548 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 },
549 { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60,
550 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 },
551 { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9,
552 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb },
553 { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45,
554 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 },
555 { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b,
556 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 },
557 { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06,
558 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c },
559 },
560 {
561 { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa,
562 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 },
563 { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f,
564 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd },
565 { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c,
566 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 },
567 { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c,
568 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 },
569 { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed,
570 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 },
571 { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6,
572 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a },
573 { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f,
574 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 },
575 { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe,
576 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 },
577 },
578};
579
Paul Bakker61b699e2014-01-22 13:35:29 +0100580static const unsigned char ripemd160_test_key[KEYS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100581{
582 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
583 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 },
584 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
585 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 },
586};
587
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100588/*
589 * Checkup routine
590 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100591int ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100592{
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100593 int i, j;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100594 unsigned char output[20];
595
596 memset( output, 0, sizeof output );
597
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100598 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100599 {
600 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100601 polarssl_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100602
Paul Bakker61b699e2014-01-22 13:35:29 +0100603 ripemd160( (const unsigned char *) ripemd160_test_input[i],
604 strlen( ripemd160_test_input[i] ),
605 output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100606
Paul Bakker61b699e2014-01-22 13:35:29 +0100607 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100608 {
609 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100610 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100611
612 return( 1 );
613 }
614
615 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100616 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100617
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100618 for( j = 0; j < KEYS; j++ )
619 {
620 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100621 polarssl_printf( " HMAC-RIPEMD-160 test #%d, key #%d: ",
622 i + 1, j + 1 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100623
Paul Bakker61b699e2014-01-22 13:35:29 +0100624 ripemd160_hmac( ripemd160_test_key[j], 20,
625 (const unsigned char *) ripemd160_test_input[i],
626 strlen( ripemd160_test_input[i] ),
627 output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100628
Paul Bakker61b699e2014-01-22 13:35:29 +0100629 if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100630 {
631 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100632 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100633
634 return( 1 );
635 }
636
637 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100638 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100639 }
640
641 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100642 polarssl_printf( "\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100643 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100644
645 return( 0 );
646}
647
Paul Bakker9af723c2014-05-01 13:03:14 +0200648#endif /* POLARSSL_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100649
Paul Bakker9af723c2014-05-01 13:03:14 +0200650#endif /* POLARSSL_RIPEMD160_C */