blob: 10e60df84b9222914c98eaf77f6da16f8f9146c9 [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
Paul Bakker61b699e2014-01-22 13:35:29 +010034#if defined(POLARSSL_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010035
Paul Bakker61b699e2014-01-22 13:35:29 +010036#include "polarssl/ripemd160.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010037
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
Paul Bakker7dc4c442014-02-01 22:50:26 +010046#if defined(POLARSSL_PLATFORM_C)
47#include "polarssl/platform.h"
48#else
49#define polarssl_printf printf
50#endif
51
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010052/*
53 * 32-bit integer manipulation macros (little endian)
54 */
55#ifndef GET_UINT32_LE
56#define GET_UINT32_LE(n,b,i) \
57{ \
58 (n) = ( (uint32_t) (b)[(i) ] ) \
59 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
60 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
61 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
62}
63#endif
64
65#ifndef PUT_UINT32_LE
66#define PUT_UINT32_LE(n,b,i) \
67{ \
68 (b)[(i) ] = (unsigned char) ( (n) ); \
69 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
70 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
71 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
72}
73#endif
74
75/*
Paul Bakker61b699e2014-01-22 13:35:29 +010076 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010077 */
Paul Bakker61b699e2014-01-22 13:35:29 +010078void ripemd160_starts( ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010079{
80 ctx->total[0] = 0;
81 ctx->total[1] = 0;
82
83 ctx->state[0] = 0x67452301;
84 ctx->state[1] = 0xEFCDAB89;
85 ctx->state[2] = 0x98BADCFE;
86 ctx->state[3] = 0x10325476;
87 ctx->state[4] = 0xC3D2E1F0;
88}
89
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010090/*
91 * Process one block
92 */
Paul Bakker61b699e2014-01-22 13:35:29 +010093void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010094{
95 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
96
97 GET_UINT32_LE( X[ 0], data, 0 );
98 GET_UINT32_LE( X[ 1], data, 4 );
99 GET_UINT32_LE( X[ 2], data, 8 );
100 GET_UINT32_LE( X[ 3], data, 12 );
101 GET_UINT32_LE( X[ 4], data, 16 );
102 GET_UINT32_LE( X[ 5], data, 20 );
103 GET_UINT32_LE( X[ 6], data, 24 );
104 GET_UINT32_LE( X[ 7], data, 28 );
105 GET_UINT32_LE( X[ 8], data, 32 );
106 GET_UINT32_LE( X[ 9], data, 36 );
107 GET_UINT32_LE( X[10], data, 40 );
108 GET_UINT32_LE( X[11], data, 44 );
109 GET_UINT32_LE( X[12], data, 48 );
110 GET_UINT32_LE( X[13], data, 52 );
111 GET_UINT32_LE( X[14], data, 56 );
112 GET_UINT32_LE( X[15], data, 60 );
113
114 A = Ap = ctx->state[0];
115 B = Bp = ctx->state[1];
116 C = Cp = ctx->state[2];
117 D = Dp = ctx->state[3];
118 E = Ep = ctx->state[4];
119
120#define F1( x, y, z ) ( x ^ y ^ z )
121#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
122#define F3( x, y, z ) ( ( x | ~y ) ^ z )
123#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
124#define F5( x, y, z ) ( x ^ ( y | ~z ) )
125
126#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
127
128#define P( a, b, c, d, e, r, s, f, k ) \
129 a += f( b, c, d ) + X[r] + k; \
130 a = S( a, s ) + e; \
131 c = S( c, 10 );
132
133#define P2( a, b, c, d, e, r, s, rp, sp ) \
134 P( a, b, c, d, e, r, s, F, K ); \
135 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
136
137#define F F1
138#define K 0x00000000
139#define Fp F5
140#define Kp 0x50A28BE6
141 P2( A, B, C, D, E, 0, 11, 5, 8 );
142 P2( E, A, B, C, D, 1, 14, 14, 9 );
143 P2( D, E, A, B, C, 2, 15, 7, 9 );
144 P2( C, D, E, A, B, 3, 12, 0, 11 );
145 P2( B, C, D, E, A, 4, 5, 9, 13 );
146 P2( A, B, C, D, E, 5, 8, 2, 15 );
147 P2( E, A, B, C, D, 6, 7, 11, 15 );
148 P2( D, E, A, B, C, 7, 9, 4, 5 );
149 P2( C, D, E, A, B, 8, 11, 13, 7 );
150 P2( B, C, D, E, A, 9, 13, 6, 7 );
151 P2( A, B, C, D, E, 10, 14, 15, 8 );
152 P2( E, A, B, C, D, 11, 15, 8, 11 );
153 P2( D, E, A, B, C, 12, 6, 1, 14 );
154 P2( C, D, E, A, B, 13, 7, 10, 14 );
155 P2( B, C, D, E, A, 14, 9, 3, 12 );
156 P2( A, B, C, D, E, 15, 8, 12, 6 );
157#undef F
158#undef K
159#undef Fp
160#undef Kp
161
162#define F F2
163#define K 0x5A827999
164#define Fp F4
165#define Kp 0x5C4DD124
166 P2( E, A, B, C, D, 7, 7, 6, 9 );
167 P2( D, E, A, B, C, 4, 6, 11, 13 );
168 P2( C, D, E, A, B, 13, 8, 3, 15 );
169 P2( B, C, D, E, A, 1, 13, 7, 7 );
170 P2( A, B, C, D, E, 10, 11, 0, 12 );
171 P2( E, A, B, C, D, 6, 9, 13, 8 );
172 P2( D, E, A, B, C, 15, 7, 5, 9 );
173 P2( C, D, E, A, B, 3, 15, 10, 11 );
174 P2( B, C, D, E, A, 12, 7, 14, 7 );
175 P2( A, B, C, D, E, 0, 12, 15, 7 );
176 P2( E, A, B, C, D, 9, 15, 8, 12 );
177 P2( D, E, A, B, C, 5, 9, 12, 7 );
178 P2( C, D, E, A, B, 2, 11, 4, 6 );
179 P2( B, C, D, E, A, 14, 7, 9, 15 );
180 P2( A, B, C, D, E, 11, 13, 1, 13 );
181 P2( E, A, B, C, D, 8, 12, 2, 11 );
182#undef F
183#undef K
184#undef Fp
185#undef Kp
186
187#define F F3
188#define K 0x6ED9EBA1
189#define Fp F3
190#define Kp 0x6D703EF3
191 P2( D, E, A, B, C, 3, 11, 15, 9 );
192 P2( C, D, E, A, B, 10, 13, 5, 7 );
193 P2( B, C, D, E, A, 14, 6, 1, 15 );
194 P2( A, B, C, D, E, 4, 7, 3, 11 );
195 P2( E, A, B, C, D, 9, 14, 7, 8 );
196 P2( D, E, A, B, C, 15, 9, 14, 6 );
197 P2( C, D, E, A, B, 8, 13, 6, 6 );
198 P2( B, C, D, E, A, 1, 15, 9, 14 );
199 P2( A, B, C, D, E, 2, 14, 11, 12 );
200 P2( E, A, B, C, D, 7, 8, 8, 13 );
201 P2( D, E, A, B, C, 0, 13, 12, 5 );
202 P2( C, D, E, A, B, 6, 6, 2, 14 );
203 P2( B, C, D, E, A, 13, 5, 10, 13 );
204 P2( A, B, C, D, E, 11, 12, 0, 13 );
205 P2( E, A, B, C, D, 5, 7, 4, 7 );
206 P2( D, E, A, B, C, 12, 5, 13, 5 );
207#undef F
208#undef K
209#undef Fp
210#undef Kp
211
212#define F F4
213#define K 0x8F1BBCDC
214#define Fp F2
215#define Kp 0x7A6D76E9
216 P2( C, D, E, A, B, 1, 11, 8, 15 );
217 P2( B, C, D, E, A, 9, 12, 6, 5 );
218 P2( A, B, C, D, E, 11, 14, 4, 8 );
219 P2( E, A, B, C, D, 10, 15, 1, 11 );
220 P2( D, E, A, B, C, 0, 14, 3, 14 );
221 P2( C, D, E, A, B, 8, 15, 11, 14 );
222 P2( B, C, D, E, A, 12, 9, 15, 6 );
223 P2( A, B, C, D, E, 4, 8, 0, 14 );
224 P2( E, A, B, C, D, 13, 9, 5, 6 );
225 P2( D, E, A, B, C, 3, 14, 12, 9 );
226 P2( C, D, E, A, B, 7, 5, 2, 12 );
227 P2( B, C, D, E, A, 15, 6, 13, 9 );
228 P2( A, B, C, D, E, 14, 8, 9, 12 );
229 P2( E, A, B, C, D, 5, 6, 7, 5 );
230 P2( D, E, A, B, C, 6, 5, 10, 15 );
231 P2( C, D, E, A, B, 2, 12, 14, 8 );
232#undef F
233#undef K
234#undef Fp
235#undef Kp
236
237#define F F5
238#define K 0xA953FD4E
239#define Fp F1
240#define Kp 0x00000000
241 P2( B, C, D, E, A, 4, 9, 12, 8 );
242 P2( A, B, C, D, E, 0, 15, 15, 5 );
243 P2( E, A, B, C, D, 5, 5, 10, 12 );
244 P2( D, E, A, B, C, 9, 11, 4, 9 );
245 P2( C, D, E, A, B, 7, 6, 1, 12 );
246 P2( B, C, D, E, A, 12, 8, 5, 5 );
247 P2( A, B, C, D, E, 2, 13, 8, 14 );
248 P2( E, A, B, C, D, 10, 12, 7, 6 );
249 P2( D, E, A, B, C, 14, 5, 6, 8 );
250 P2( C, D, E, A, B, 1, 12, 2, 13 );
251 P2( B, C, D, E, A, 3, 13, 13, 6 );
252 P2( A, B, C, D, E, 8, 14, 14, 5 );
253 P2( E, A, B, C, D, 11, 11, 0, 15 );
254 P2( D, E, A, B, C, 6, 8, 3, 13 );
255 P2( C, D, E, A, B, 15, 5, 9, 11 );
256 P2( B, C, D, E, A, 13, 6, 11, 11 );
257#undef F
258#undef K
259#undef Fp
260#undef Kp
261
262 C = ctx->state[1] + C + Dp;
263 ctx->state[1] = ctx->state[2] + D + Ep;
264 ctx->state[2] = ctx->state[3] + E + Ap;
265 ctx->state[3] = ctx->state[4] + A + Bp;
266 ctx->state[4] = ctx->state[0] + B + Cp;
267 ctx->state[0] = C;
268}
269
270/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100271 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100272 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100273void ripemd160_update( ripemd160_context *ctx,
274 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100275{
276 size_t fill;
277 uint32_t left;
278
279 if( ilen <= 0 )
280 return;
281
282 left = ctx->total[0] & 0x3F;
283 fill = 64 - left;
284
285 ctx->total[0] += (uint32_t) ilen;
286 ctx->total[0] &= 0xFFFFFFFF;
287
288 if( ctx->total[0] < (uint32_t) ilen )
289 ctx->total[1]++;
290
291 if( left && ilen >= fill )
292 {
293 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker61b699e2014-01-22 13:35:29 +0100294 ripemd160_process( ctx, ctx->buffer );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100295 input += fill;
296 ilen -= fill;
297 left = 0;
298 }
299
300 while( ilen >= 64 )
301 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100302 ripemd160_process( ctx, input );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100303 input += 64;
304 ilen -= 64;
305 }
306
307 if( ilen > 0 )
308 {
309 memcpy( (void *) (ctx->buffer + left), input, ilen );
310 }
311}
312
Paul Bakker61b699e2014-01-22 13:35:29 +0100313static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100314{
315 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
319};
320
321/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100322 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100323 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100324void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100325{
326 uint32_t last, padn;
327 uint32_t high, low;
328 unsigned char msglen[8];
329
330 high = ( ctx->total[0] >> 29 )
331 | ( ctx->total[1] << 3 );
332 low = ( ctx->total[0] << 3 );
333
334 PUT_UINT32_LE( low, msglen, 0 );
335 PUT_UINT32_LE( high, msglen, 4 );
336
337 last = ctx->total[0] & 0x3F;
338 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
339
Paul Bakker61b699e2014-01-22 13:35:29 +0100340 ripemd160_update( ctx, ripemd160_padding, padn );
341 ripemd160_update( ctx, msglen, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100342
343 PUT_UINT32_LE( ctx->state[0], output, 0 );
344 PUT_UINT32_LE( ctx->state[1], output, 4 );
345 PUT_UINT32_LE( ctx->state[2], output, 8 );
346 PUT_UINT32_LE( ctx->state[3], output, 12 );
347 PUT_UINT32_LE( ctx->state[4], output, 16 );
348}
349
350/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100351 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100352 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100353void ripemd160( const unsigned char *input, size_t ilen,
354 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100355{
Paul Bakker61b699e2014-01-22 13:35:29 +0100356 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100357
Paul Bakker61b699e2014-01-22 13:35:29 +0100358 ripemd160_starts( &ctx );
359 ripemd160_update( &ctx, input, ilen );
360 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361
Paul Bakker61b699e2014-01-22 13:35:29 +0100362 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100363}
364
365#if defined(POLARSSL_FS_IO)
366/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100367 * output = RIPEMD-160( file contents )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100368 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100369int ripemd160_file( const char *path, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100370{
371 FILE *f;
372 size_t n;
Paul Bakker61b699e2014-01-22 13:35:29 +0100373 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100374 unsigned char buf[1024];
375
376 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker61b699e2014-01-22 13:35:29 +0100377 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100378
Paul Bakker61b699e2014-01-22 13:35:29 +0100379 ripemd160_starts( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100380
381 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100382 ripemd160_update( &ctx, buf, n );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100383
Paul Bakker61b699e2014-01-22 13:35:29 +0100384 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100385
Paul Bakker61b699e2014-01-22 13:35:29 +0100386 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100387
388 if( ferror( f ) != 0 )
389 {
390 fclose( f );
Paul Bakker61b699e2014-01-22 13:35:29 +0100391 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100392 }
393
394 fclose( f );
395 return( 0 );
396}
397#endif /* POLARSSL_FS_IO */
398
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100399/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100400 * RIPEMD-160 HMAC context setup
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100401 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100402void ripemd160_hmac_starts( ripemd160_context *ctx,
403 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100404{
405 size_t i;
406 unsigned char sum[20];
407
408 if( keylen > 64 )
409 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100410 ripemd160( key, keylen, sum );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100411 keylen = 20;
412 key = sum;
413 }
414
415 memset( ctx->ipad, 0x36, 64 );
416 memset( ctx->opad, 0x5C, 64 );
417
418 for( i = 0; i < keylen; i++ )
419 {
420 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
421 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
422 }
423
Paul Bakker61b699e2014-01-22 13:35:29 +0100424 ripemd160_starts( ctx );
425 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100426
427 memset( sum, 0, sizeof( sum ) );
428}
429
430/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100431 * RIPEMD-160 HMAC process buffer
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100432 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100433void ripemd160_hmac_update( ripemd160_context *ctx,
434 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100435{
Paul Bakker61b699e2014-01-22 13:35:29 +0100436 ripemd160_update( ctx, input, ilen );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100437}
438
439/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100440 * RIPEMD-160 HMAC final digest
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100441 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100442void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100443{
444 unsigned char tmpbuf[20];
445
Paul Bakker61b699e2014-01-22 13:35:29 +0100446 ripemd160_finish( ctx, tmpbuf );
447 ripemd160_starts( ctx );
448 ripemd160_update( ctx, ctx->opad, 64 );
449 ripemd160_update( ctx, tmpbuf, 20 );
450 ripemd160_finish( ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100451
452 memset( tmpbuf, 0, sizeof( tmpbuf ) );
453}
454
455/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100456 * RIPEMD-160 HMAC context reset
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100457 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100458void ripemd160_hmac_reset( ripemd160_context *ctx )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100459{
Paul Bakker61b699e2014-01-22 13:35:29 +0100460 ripemd160_starts( ctx );
461 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100462}
463
464/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100465 * output = HMAC-RIPEMD-160( hmac key, input buffer )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100466 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100467void ripemd160_hmac( const unsigned char *key, size_t keylen,
468 const unsigned char *input, size_t ilen,
469 unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100470{
Paul Bakker61b699e2014-01-22 13:35:29 +0100471 ripemd160_context ctx;
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100472
Paul Bakker61b699e2014-01-22 13:35:29 +0100473 ripemd160_hmac_starts( &ctx, key, keylen );
474 ripemd160_hmac_update( &ctx, input, ilen );
475 ripemd160_hmac_finish( &ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100476
Paul Bakker61b699e2014-01-22 13:35:29 +0100477 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100478}
479
480
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100481#if defined(POLARSSL_SELF_TEST)
482/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100483 * Test vectors from the RIPEMD-160 paper and
484 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100486#define TESTS 8
487#define KEYS 2
Paul Bakker61b699e2014-01-22 13:35:29 +0100488static const char *ripemd160_test_input[TESTS] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100489{
490 "",
491 "a",
492 "abc",
493 "message digest",
494 "abcdefghijklmnopqrstuvwxyz",
495 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
496 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
497 "1234567890123456789012345678901234567890"
498 "1234567890123456789012345678901234567890",
499};
500
Paul Bakker61b699e2014-01-22 13:35:29 +0100501static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100502{
503 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
504 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
505 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
506 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
507 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
508 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
509 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
510 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
511 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
512 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
513 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
514 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
515 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
516 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
517 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
518 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
519};
520
Paul Bakker61b699e2014-01-22 13:35:29 +0100521static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100522{
523 {
524 { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b,
525 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 },
526 { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39,
527 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc },
528 { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7,
529 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 },
530 { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60,
531 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 },
532 { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9,
533 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb },
534 { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45,
535 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 },
536 { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b,
537 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 },
538 { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06,
539 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c },
540 },
541 {
542 { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa,
543 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 },
544 { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f,
545 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd },
546 { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c,
547 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 },
548 { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c,
549 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 },
550 { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed,
551 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 },
552 { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6,
553 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a },
554 { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f,
555 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 },
556 { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe,
557 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 },
558 },
559};
560
Paul Bakker61b699e2014-01-22 13:35:29 +0100561static const unsigned char ripemd160_test_key[KEYS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100562{
563 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
564 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 },
565 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
566 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 },
567};
568
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100569/*
570 * Checkup routine
571 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100572int ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100573{
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100574 int i, j;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100575 unsigned char output[20];
576
577 memset( output, 0, sizeof output );
578
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100579 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100580 {
581 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100582 polarssl_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100583
Paul Bakker61b699e2014-01-22 13:35:29 +0100584 ripemd160( (const unsigned char *) ripemd160_test_input[i],
585 strlen( ripemd160_test_input[i] ),
586 output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100587
Paul Bakker61b699e2014-01-22 13:35:29 +0100588 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100589 {
590 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100591 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100592
593 return( 1 );
594 }
595
596 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100597 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100598
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100599 for( j = 0; j < KEYS; j++ )
600 {
601 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100602 polarssl_printf( " HMAC-RIPEMD-160 test #%d, key #%d: ",
603 i + 1, j + 1 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100604
Paul Bakker61b699e2014-01-22 13:35:29 +0100605 ripemd160_hmac( ripemd160_test_key[j], 20,
606 (const unsigned char *) ripemd160_test_input[i],
607 strlen( ripemd160_test_input[i] ),
608 output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100609
Paul Bakker61b699e2014-01-22 13:35:29 +0100610 if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100611 {
612 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100613 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100614
615 return( 1 );
616 }
617
618 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100619 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100620 }
621
622 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100623 polarssl_printf( "\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100624 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100625
626 return( 0 );
627}
628
629#endif
630
631#endif