blob: 569cbdec869670391497006fcc494818efe6bfb6 [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
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/*
Paul Bakker61b699e2014-01-22 13:35:29 +010070 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010071 */
Paul Bakker61b699e2014-01-22 13:35:29 +010072void ripemd160_starts( ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010073{
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
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010084/*
85 * Process one block
86 */
Paul Bakker61b699e2014-01-22 13:35:29 +010087void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010088{
89 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
90
91 GET_UINT32_LE( X[ 0], data, 0 );
92 GET_UINT32_LE( X[ 1], data, 4 );
93 GET_UINT32_LE( X[ 2], data, 8 );
94 GET_UINT32_LE( X[ 3], data, 12 );
95 GET_UINT32_LE( X[ 4], data, 16 );
96 GET_UINT32_LE( X[ 5], data, 20 );
97 GET_UINT32_LE( X[ 6], data, 24 );
98 GET_UINT32_LE( X[ 7], data, 28 );
99 GET_UINT32_LE( X[ 8], data, 32 );
100 GET_UINT32_LE( X[ 9], data, 36 );
101 GET_UINT32_LE( X[10], data, 40 );
102 GET_UINT32_LE( X[11], data, 44 );
103 GET_UINT32_LE( X[12], data, 48 );
104 GET_UINT32_LE( X[13], data, 52 );
105 GET_UINT32_LE( X[14], data, 56 );
106 GET_UINT32_LE( X[15], data, 60 );
107
108 A = Ap = ctx->state[0];
109 B = Bp = ctx->state[1];
110 C = Cp = ctx->state[2];
111 D = Dp = ctx->state[3];
112 E = Ep = ctx->state[4];
113
114#define F1( x, y, z ) ( x ^ y ^ z )
115#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
116#define F3( x, y, z ) ( ( x | ~y ) ^ z )
117#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
118#define F5( x, y, z ) ( x ^ ( y | ~z ) )
119
120#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
121
122#define P( a, b, c, d, e, r, s, f, k ) \
123 a += f( b, c, d ) + X[r] + k; \
124 a = S( a, s ) + e; \
125 c = S( c, 10 );
126
127#define P2( a, b, c, d, e, r, s, rp, sp ) \
128 P( a, b, c, d, e, r, s, F, K ); \
129 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
130
131#define F F1
132#define K 0x00000000
133#define Fp F5
134#define Kp 0x50A28BE6
135 P2( A, B, C, D, E, 0, 11, 5, 8 );
136 P2( E, A, B, C, D, 1, 14, 14, 9 );
137 P2( D, E, A, B, C, 2, 15, 7, 9 );
138 P2( C, D, E, A, B, 3, 12, 0, 11 );
139 P2( B, C, D, E, A, 4, 5, 9, 13 );
140 P2( A, B, C, D, E, 5, 8, 2, 15 );
141 P2( E, A, B, C, D, 6, 7, 11, 15 );
142 P2( D, E, A, B, C, 7, 9, 4, 5 );
143 P2( C, D, E, A, B, 8, 11, 13, 7 );
144 P2( B, C, D, E, A, 9, 13, 6, 7 );
145 P2( A, B, C, D, E, 10, 14, 15, 8 );
146 P2( E, A, B, C, D, 11, 15, 8, 11 );
147 P2( D, E, A, B, C, 12, 6, 1, 14 );
148 P2( C, D, E, A, B, 13, 7, 10, 14 );
149 P2( B, C, D, E, A, 14, 9, 3, 12 );
150 P2( A, B, C, D, E, 15, 8, 12, 6 );
151#undef F
152#undef K
153#undef Fp
154#undef Kp
155
156#define F F2
157#define K 0x5A827999
158#define Fp F4
159#define Kp 0x5C4DD124
160 P2( E, A, B, C, D, 7, 7, 6, 9 );
161 P2( D, E, A, B, C, 4, 6, 11, 13 );
162 P2( C, D, E, A, B, 13, 8, 3, 15 );
163 P2( B, C, D, E, A, 1, 13, 7, 7 );
164 P2( A, B, C, D, E, 10, 11, 0, 12 );
165 P2( E, A, B, C, D, 6, 9, 13, 8 );
166 P2( D, E, A, B, C, 15, 7, 5, 9 );
167 P2( C, D, E, A, B, 3, 15, 10, 11 );
168 P2( B, C, D, E, A, 12, 7, 14, 7 );
169 P2( A, B, C, D, E, 0, 12, 15, 7 );
170 P2( E, A, B, C, D, 9, 15, 8, 12 );
171 P2( D, E, A, B, C, 5, 9, 12, 7 );
172 P2( C, D, E, A, B, 2, 11, 4, 6 );
173 P2( B, C, D, E, A, 14, 7, 9, 15 );
174 P2( A, B, C, D, E, 11, 13, 1, 13 );
175 P2( E, A, B, C, D, 8, 12, 2, 11 );
176#undef F
177#undef K
178#undef Fp
179#undef Kp
180
181#define F F3
182#define K 0x6ED9EBA1
183#define Fp F3
184#define Kp 0x6D703EF3
185 P2( D, E, A, B, C, 3, 11, 15, 9 );
186 P2( C, D, E, A, B, 10, 13, 5, 7 );
187 P2( B, C, D, E, A, 14, 6, 1, 15 );
188 P2( A, B, C, D, E, 4, 7, 3, 11 );
189 P2( E, A, B, C, D, 9, 14, 7, 8 );
190 P2( D, E, A, B, C, 15, 9, 14, 6 );
191 P2( C, D, E, A, B, 8, 13, 6, 6 );
192 P2( B, C, D, E, A, 1, 15, 9, 14 );
193 P2( A, B, C, D, E, 2, 14, 11, 12 );
194 P2( E, A, B, C, D, 7, 8, 8, 13 );
195 P2( D, E, A, B, C, 0, 13, 12, 5 );
196 P2( C, D, E, A, B, 6, 6, 2, 14 );
197 P2( B, C, D, E, A, 13, 5, 10, 13 );
198 P2( A, B, C, D, E, 11, 12, 0, 13 );
199 P2( E, A, B, C, D, 5, 7, 4, 7 );
200 P2( D, E, A, B, C, 12, 5, 13, 5 );
201#undef F
202#undef K
203#undef Fp
204#undef Kp
205
206#define F F4
207#define K 0x8F1BBCDC
208#define Fp F2
209#define Kp 0x7A6D76E9
210 P2( C, D, E, A, B, 1, 11, 8, 15 );
211 P2( B, C, D, E, A, 9, 12, 6, 5 );
212 P2( A, B, C, D, E, 11, 14, 4, 8 );
213 P2( E, A, B, C, D, 10, 15, 1, 11 );
214 P2( D, E, A, B, C, 0, 14, 3, 14 );
215 P2( C, D, E, A, B, 8, 15, 11, 14 );
216 P2( B, C, D, E, A, 12, 9, 15, 6 );
217 P2( A, B, C, D, E, 4, 8, 0, 14 );
218 P2( E, A, B, C, D, 13, 9, 5, 6 );
219 P2( D, E, A, B, C, 3, 14, 12, 9 );
220 P2( C, D, E, A, B, 7, 5, 2, 12 );
221 P2( B, C, D, E, A, 15, 6, 13, 9 );
222 P2( A, B, C, D, E, 14, 8, 9, 12 );
223 P2( E, A, B, C, D, 5, 6, 7, 5 );
224 P2( D, E, A, B, C, 6, 5, 10, 15 );
225 P2( C, D, E, A, B, 2, 12, 14, 8 );
226#undef F
227#undef K
228#undef Fp
229#undef Kp
230
231#define F F5
232#define K 0xA953FD4E
233#define Fp F1
234#define Kp 0x00000000
235 P2( B, C, D, E, A, 4, 9, 12, 8 );
236 P2( A, B, C, D, E, 0, 15, 15, 5 );
237 P2( E, A, B, C, D, 5, 5, 10, 12 );
238 P2( D, E, A, B, C, 9, 11, 4, 9 );
239 P2( C, D, E, A, B, 7, 6, 1, 12 );
240 P2( B, C, D, E, A, 12, 8, 5, 5 );
241 P2( A, B, C, D, E, 2, 13, 8, 14 );
242 P2( E, A, B, C, D, 10, 12, 7, 6 );
243 P2( D, E, A, B, C, 14, 5, 6, 8 );
244 P2( C, D, E, A, B, 1, 12, 2, 13 );
245 P2( B, C, D, E, A, 3, 13, 13, 6 );
246 P2( A, B, C, D, E, 8, 14, 14, 5 );
247 P2( E, A, B, C, D, 11, 11, 0, 15 );
248 P2( D, E, A, B, C, 6, 8, 3, 13 );
249 P2( C, D, E, A, B, 15, 5, 9, 11 );
250 P2( B, C, D, E, A, 13, 6, 11, 11 );
251#undef F
252#undef K
253#undef Fp
254#undef Kp
255
256 C = ctx->state[1] + C + Dp;
257 ctx->state[1] = ctx->state[2] + D + Ep;
258 ctx->state[2] = ctx->state[3] + E + Ap;
259 ctx->state[3] = ctx->state[4] + A + Bp;
260 ctx->state[4] = ctx->state[0] + B + Cp;
261 ctx->state[0] = C;
262}
263
264/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100265 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100266 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100267void ripemd160_update( ripemd160_context *ctx,
268 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100269{
270 size_t fill;
271 uint32_t left;
272
273 if( ilen <= 0 )
274 return;
275
276 left = ctx->total[0] & 0x3F;
277 fill = 64 - left;
278
279 ctx->total[0] += (uint32_t) ilen;
280 ctx->total[0] &= 0xFFFFFFFF;
281
282 if( ctx->total[0] < (uint32_t) ilen )
283 ctx->total[1]++;
284
285 if( left && ilen >= fill )
286 {
287 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker61b699e2014-01-22 13:35:29 +0100288 ripemd160_process( ctx, ctx->buffer );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100289 input += fill;
290 ilen -= fill;
291 left = 0;
292 }
293
294 while( ilen >= 64 )
295 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100296 ripemd160_process( ctx, input );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297 input += 64;
298 ilen -= 64;
299 }
300
301 if( ilen > 0 )
302 {
303 memcpy( (void *) (ctx->buffer + left), input, ilen );
304 }
305}
306
Paul Bakker61b699e2014-01-22 13:35:29 +0100307static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100308{
309 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
313};
314
315/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100316 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100317 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100318void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100319{
320 uint32_t last, padn;
321 uint32_t high, low;
322 unsigned char msglen[8];
323
324 high = ( ctx->total[0] >> 29 )
325 | ( ctx->total[1] << 3 );
326 low = ( ctx->total[0] << 3 );
327
328 PUT_UINT32_LE( low, msglen, 0 );
329 PUT_UINT32_LE( high, msglen, 4 );
330
331 last = ctx->total[0] & 0x3F;
332 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
333
Paul Bakker61b699e2014-01-22 13:35:29 +0100334 ripemd160_update( ctx, ripemd160_padding, padn );
335 ripemd160_update( ctx, msglen, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100336
337 PUT_UINT32_LE( ctx->state[0], output, 0 );
338 PUT_UINT32_LE( ctx->state[1], output, 4 );
339 PUT_UINT32_LE( ctx->state[2], output, 8 );
340 PUT_UINT32_LE( ctx->state[3], output, 12 );
341 PUT_UINT32_LE( ctx->state[4], output, 16 );
342}
343
344/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100345 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100346 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100347void ripemd160( const unsigned char *input, size_t ilen,
348 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100349{
Paul Bakker61b699e2014-01-22 13:35:29 +0100350 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100351
Paul Bakker61b699e2014-01-22 13:35:29 +0100352 ripemd160_starts( &ctx );
353 ripemd160_update( &ctx, input, ilen );
354 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100355
Paul Bakker61b699e2014-01-22 13:35:29 +0100356 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100357}
358
359#if defined(POLARSSL_FS_IO)
360/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100361 * output = RIPEMD-160( file contents )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100362 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100363int ripemd160_file( const char *path, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364{
365 FILE *f;
366 size_t n;
Paul Bakker61b699e2014-01-22 13:35:29 +0100367 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100368 unsigned char buf[1024];
369
370 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker61b699e2014-01-22 13:35:29 +0100371 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372
Paul Bakker61b699e2014-01-22 13:35:29 +0100373 ripemd160_starts( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100374
375 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100376 ripemd160_update( &ctx, buf, n );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100377
Paul Bakker61b699e2014-01-22 13:35:29 +0100378 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100379
Paul Bakker61b699e2014-01-22 13:35:29 +0100380 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100381
382 if( ferror( f ) != 0 )
383 {
384 fclose( f );
Paul Bakker61b699e2014-01-22 13:35:29 +0100385 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100386 }
387
388 fclose( f );
389 return( 0 );
390}
391#endif /* POLARSSL_FS_IO */
392
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100393/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100394 * RIPEMD-160 HMAC context setup
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100395 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100396void ripemd160_hmac_starts( ripemd160_context *ctx,
397 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100398{
399 size_t i;
400 unsigned char sum[20];
401
402 if( keylen > 64 )
403 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100404 ripemd160( key, keylen, sum );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100405 keylen = 20;
406 key = sum;
407 }
408
409 memset( ctx->ipad, 0x36, 64 );
410 memset( ctx->opad, 0x5C, 64 );
411
412 for( i = 0; i < keylen; i++ )
413 {
414 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
415 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
416 }
417
Paul Bakker61b699e2014-01-22 13:35:29 +0100418 ripemd160_starts( ctx );
419 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100420
421 memset( sum, 0, sizeof( sum ) );
422}
423
424/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100425 * RIPEMD-160 HMAC process buffer
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100426 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100427void ripemd160_hmac_update( ripemd160_context *ctx,
428 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100429{
Paul Bakker61b699e2014-01-22 13:35:29 +0100430 ripemd160_update( ctx, input, ilen );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100431}
432
433/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100434 * RIPEMD-160 HMAC final digest
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100435 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100436void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100437{
438 unsigned char tmpbuf[20];
439
Paul Bakker61b699e2014-01-22 13:35:29 +0100440 ripemd160_finish( ctx, tmpbuf );
441 ripemd160_starts( ctx );
442 ripemd160_update( ctx, ctx->opad, 64 );
443 ripemd160_update( ctx, tmpbuf, 20 );
444 ripemd160_finish( ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100445
446 memset( tmpbuf, 0, sizeof( tmpbuf ) );
447}
448
449/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100450 * RIPEMD-160 HMAC context reset
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100451 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100452void ripemd160_hmac_reset( ripemd160_context *ctx )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100453{
Paul Bakker61b699e2014-01-22 13:35:29 +0100454 ripemd160_starts( ctx );
455 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100456}
457
458/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100459 * output = HMAC-RIPEMD-160( hmac key, input buffer )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100460 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100461void ripemd160_hmac( const unsigned char *key, size_t keylen,
462 const unsigned char *input, size_t ilen,
463 unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100464{
Paul Bakker61b699e2014-01-22 13:35:29 +0100465 ripemd160_context ctx;
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100466
Paul Bakker61b699e2014-01-22 13:35:29 +0100467 ripemd160_hmac_starts( &ctx, key, keylen );
468 ripemd160_hmac_update( &ctx, input, ilen );
469 ripemd160_hmac_finish( &ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100470
Paul Bakker61b699e2014-01-22 13:35:29 +0100471 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100472}
473
474
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475#if defined(POLARSSL_SELF_TEST)
476/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100477 * Test vectors from the RIPEMD-160 paper and
478 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100479 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100480#define TESTS 8
481#define KEYS 2
Paul Bakker61b699e2014-01-22 13:35:29 +0100482static const char *ripemd160_test_input[TESTS] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100483{
484 "",
485 "a",
486 "abc",
487 "message digest",
488 "abcdefghijklmnopqrstuvwxyz",
489 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
490 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
491 "1234567890123456789012345678901234567890"
492 "1234567890123456789012345678901234567890",
493};
494
Paul Bakker61b699e2014-01-22 13:35:29 +0100495static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100496{
497 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
498 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
499 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
500 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
501 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
502 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
503 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
504 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
505 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
506 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
507 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
508 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
509 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
510 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
511 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
512 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
513};
514
Paul Bakker61b699e2014-01-22 13:35:29 +0100515static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100516{
517 {
518 { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b,
519 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 },
520 { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39,
521 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc },
522 { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7,
523 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 },
524 { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60,
525 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 },
526 { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9,
527 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb },
528 { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45,
529 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 },
530 { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b,
531 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 },
532 { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06,
533 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c },
534 },
535 {
536 { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa,
537 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 },
538 { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f,
539 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd },
540 { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c,
541 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 },
542 { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c,
543 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 },
544 { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed,
545 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 },
546 { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6,
547 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a },
548 { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f,
549 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 },
550 { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe,
551 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 },
552 },
553};
554
Paul Bakker61b699e2014-01-22 13:35:29 +0100555static const unsigned char ripemd160_test_key[KEYS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100556{
557 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
558 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 },
559 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
560 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 },
561};
562
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100563/*
564 * Checkup routine
565 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100566int ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100567{
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100568 int i, j;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100569 unsigned char output[20];
570
571 memset( output, 0, sizeof output );
572
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100573 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100574 {
575 if( verbose != 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100576 printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100577
Paul Bakker61b699e2014-01-22 13:35:29 +0100578 ripemd160( (const unsigned char *) ripemd160_test_input[i],
579 strlen( ripemd160_test_input[i] ),
580 output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100581
Paul Bakker61b699e2014-01-22 13:35:29 +0100582 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100583 {
584 if( verbose != 0 )
585 printf( "failed\n" );
586
587 return( 1 );
588 }
589
590 if( verbose != 0 )
591 printf( "passed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100592
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100593 for( j = 0; j < KEYS; j++ )
594 {
595 if( verbose != 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100596 printf( " HMAC-RIPEMD-160 test #%d, key #%d: ", i + 1, j + 1 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100597
Paul Bakker61b699e2014-01-22 13:35:29 +0100598 ripemd160_hmac( ripemd160_test_key[j], 20,
599 (const unsigned char *) ripemd160_test_input[i],
600 strlen( ripemd160_test_input[i] ),
601 output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100602
Paul Bakker61b699e2014-01-22 13:35:29 +0100603 if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100604 {
605 if( verbose != 0 )
606 printf( "failed\n" );
607
608 return( 1 );
609 }
610
611 if( verbose != 0 )
612 printf( "passed\n" );
613 }
614
615 if( verbose != 0 )
616 printf( "\n" );
617 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100618
619 return( 0 );
620}
621
622#endif
623
624#endif