blob: 73da510e2a79d18a87b326c7d9db34423e2b7d65 [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
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#if !defined(POLARSSL_CONFIG_FILE)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010033#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020034#else
35#include POLARSSL_CONFIG_FILE
36#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010037
Paul Bakker61b699e2014-01-22 13:35:29 +010038#if defined(POLARSSL_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010039
Paul Bakker61b699e2014-01-22 13:35:29 +010040#include "polarssl/ripemd160.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010041
42#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
43#include <stdio.h>
44#endif
45
46#if defined(POLARSSL_SELF_TEST)
47#include <string.h>
48#endif
49
Paul Bakker7dc4c442014-02-01 22:50:26 +010050#if defined(POLARSSL_PLATFORM_C)
51#include "polarssl/platform.h"
52#else
53#define polarssl_printf printf
54#endif
55
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010056/*
57 * 32-bit integer manipulation macros (little endian)
58 */
59#ifndef GET_UINT32_LE
60#define GET_UINT32_LE(n,b,i) \
61{ \
62 (n) = ( (uint32_t) (b)[(i) ] ) \
63 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
64 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
65 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
66}
67#endif
68
69#ifndef PUT_UINT32_LE
70#define PUT_UINT32_LE(n,b,i) \
71{ \
72 (b)[(i) ] = (unsigned char) ( (n) ); \
73 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
74 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
75 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
76}
77#endif
78
79/*
Paul Bakker61b699e2014-01-22 13:35:29 +010080 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010081 */
Paul Bakker61b699e2014-01-22 13:35:29 +010082void ripemd160_starts( ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010083{
84 ctx->total[0] = 0;
85 ctx->total[1] = 0;
86
87 ctx->state[0] = 0x67452301;
88 ctx->state[1] = 0xEFCDAB89;
89 ctx->state[2] = 0x98BADCFE;
90 ctx->state[3] = 0x10325476;
91 ctx->state[4] = 0xC3D2E1F0;
92}
93
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010094/*
95 * Process one block
96 */
Paul Bakker61b699e2014-01-22 13:35:29 +010097void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010098{
99 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
100
101 GET_UINT32_LE( X[ 0], data, 0 );
102 GET_UINT32_LE( X[ 1], data, 4 );
103 GET_UINT32_LE( X[ 2], data, 8 );
104 GET_UINT32_LE( X[ 3], data, 12 );
105 GET_UINT32_LE( X[ 4], data, 16 );
106 GET_UINT32_LE( X[ 5], data, 20 );
107 GET_UINT32_LE( X[ 6], data, 24 );
108 GET_UINT32_LE( X[ 7], data, 28 );
109 GET_UINT32_LE( X[ 8], data, 32 );
110 GET_UINT32_LE( X[ 9], data, 36 );
111 GET_UINT32_LE( X[10], data, 40 );
112 GET_UINT32_LE( X[11], data, 44 );
113 GET_UINT32_LE( X[12], data, 48 );
114 GET_UINT32_LE( X[13], data, 52 );
115 GET_UINT32_LE( X[14], data, 56 );
116 GET_UINT32_LE( X[15], data, 60 );
117
118 A = Ap = ctx->state[0];
119 B = Bp = ctx->state[1];
120 C = Cp = ctx->state[2];
121 D = Dp = ctx->state[3];
122 E = Ep = ctx->state[4];
123
124#define F1( x, y, z ) ( x ^ y ^ z )
125#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
126#define F3( x, y, z ) ( ( x | ~y ) ^ z )
127#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
128#define F5( x, y, z ) ( x ^ ( y | ~z ) )
129
130#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
131
132#define P( a, b, c, d, e, r, s, f, k ) \
133 a += f( b, c, d ) + X[r] + k; \
134 a = S( a, s ) + e; \
135 c = S( c, 10 );
136
137#define P2( a, b, c, d, e, r, s, rp, sp ) \
138 P( a, b, c, d, e, r, s, F, K ); \
139 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
140
141#define F F1
142#define K 0x00000000
143#define Fp F5
144#define Kp 0x50A28BE6
145 P2( A, B, C, D, E, 0, 11, 5, 8 );
146 P2( E, A, B, C, D, 1, 14, 14, 9 );
147 P2( D, E, A, B, C, 2, 15, 7, 9 );
148 P2( C, D, E, A, B, 3, 12, 0, 11 );
149 P2( B, C, D, E, A, 4, 5, 9, 13 );
150 P2( A, B, C, D, E, 5, 8, 2, 15 );
151 P2( E, A, B, C, D, 6, 7, 11, 15 );
152 P2( D, E, A, B, C, 7, 9, 4, 5 );
153 P2( C, D, E, A, B, 8, 11, 13, 7 );
154 P2( B, C, D, E, A, 9, 13, 6, 7 );
155 P2( A, B, C, D, E, 10, 14, 15, 8 );
156 P2( E, A, B, C, D, 11, 15, 8, 11 );
157 P2( D, E, A, B, C, 12, 6, 1, 14 );
158 P2( C, D, E, A, B, 13, 7, 10, 14 );
159 P2( B, C, D, E, A, 14, 9, 3, 12 );
160 P2( A, B, C, D, E, 15, 8, 12, 6 );
161#undef F
162#undef K
163#undef Fp
164#undef Kp
165
166#define F F2
167#define K 0x5A827999
168#define Fp F4
169#define Kp 0x5C4DD124
170 P2( E, A, B, C, D, 7, 7, 6, 9 );
171 P2( D, E, A, B, C, 4, 6, 11, 13 );
172 P2( C, D, E, A, B, 13, 8, 3, 15 );
173 P2( B, C, D, E, A, 1, 13, 7, 7 );
174 P2( A, B, C, D, E, 10, 11, 0, 12 );
175 P2( E, A, B, C, D, 6, 9, 13, 8 );
176 P2( D, E, A, B, C, 15, 7, 5, 9 );
177 P2( C, D, E, A, B, 3, 15, 10, 11 );
178 P2( B, C, D, E, A, 12, 7, 14, 7 );
179 P2( A, B, C, D, E, 0, 12, 15, 7 );
180 P2( E, A, B, C, D, 9, 15, 8, 12 );
181 P2( D, E, A, B, C, 5, 9, 12, 7 );
182 P2( C, D, E, A, B, 2, 11, 4, 6 );
183 P2( B, C, D, E, A, 14, 7, 9, 15 );
184 P2( A, B, C, D, E, 11, 13, 1, 13 );
185 P2( E, A, B, C, D, 8, 12, 2, 11 );
186#undef F
187#undef K
188#undef Fp
189#undef Kp
190
191#define F F3
192#define K 0x6ED9EBA1
193#define Fp F3
194#define Kp 0x6D703EF3
195 P2( D, E, A, B, C, 3, 11, 15, 9 );
196 P2( C, D, E, A, B, 10, 13, 5, 7 );
197 P2( B, C, D, E, A, 14, 6, 1, 15 );
198 P2( A, B, C, D, E, 4, 7, 3, 11 );
199 P2( E, A, B, C, D, 9, 14, 7, 8 );
200 P2( D, E, A, B, C, 15, 9, 14, 6 );
201 P2( C, D, E, A, B, 8, 13, 6, 6 );
202 P2( B, C, D, E, A, 1, 15, 9, 14 );
203 P2( A, B, C, D, E, 2, 14, 11, 12 );
204 P2( E, A, B, C, D, 7, 8, 8, 13 );
205 P2( D, E, A, B, C, 0, 13, 12, 5 );
206 P2( C, D, E, A, B, 6, 6, 2, 14 );
207 P2( B, C, D, E, A, 13, 5, 10, 13 );
208 P2( A, B, C, D, E, 11, 12, 0, 13 );
209 P2( E, A, B, C, D, 5, 7, 4, 7 );
210 P2( D, E, A, B, C, 12, 5, 13, 5 );
211#undef F
212#undef K
213#undef Fp
214#undef Kp
215
216#define F F4
217#define K 0x8F1BBCDC
218#define Fp F2
219#define Kp 0x7A6D76E9
220 P2( C, D, E, A, B, 1, 11, 8, 15 );
221 P2( B, C, D, E, A, 9, 12, 6, 5 );
222 P2( A, B, C, D, E, 11, 14, 4, 8 );
223 P2( E, A, B, C, D, 10, 15, 1, 11 );
224 P2( D, E, A, B, C, 0, 14, 3, 14 );
225 P2( C, D, E, A, B, 8, 15, 11, 14 );
226 P2( B, C, D, E, A, 12, 9, 15, 6 );
227 P2( A, B, C, D, E, 4, 8, 0, 14 );
228 P2( E, A, B, C, D, 13, 9, 5, 6 );
229 P2( D, E, A, B, C, 3, 14, 12, 9 );
230 P2( C, D, E, A, B, 7, 5, 2, 12 );
231 P2( B, C, D, E, A, 15, 6, 13, 9 );
232 P2( A, B, C, D, E, 14, 8, 9, 12 );
233 P2( E, A, B, C, D, 5, 6, 7, 5 );
234 P2( D, E, A, B, C, 6, 5, 10, 15 );
235 P2( C, D, E, A, B, 2, 12, 14, 8 );
236#undef F
237#undef K
238#undef Fp
239#undef Kp
240
241#define F F5
242#define K 0xA953FD4E
243#define Fp F1
244#define Kp 0x00000000
245 P2( B, C, D, E, A, 4, 9, 12, 8 );
246 P2( A, B, C, D, E, 0, 15, 15, 5 );
247 P2( E, A, B, C, D, 5, 5, 10, 12 );
248 P2( D, E, A, B, C, 9, 11, 4, 9 );
249 P2( C, D, E, A, B, 7, 6, 1, 12 );
250 P2( B, C, D, E, A, 12, 8, 5, 5 );
251 P2( A, B, C, D, E, 2, 13, 8, 14 );
252 P2( E, A, B, C, D, 10, 12, 7, 6 );
253 P2( D, E, A, B, C, 14, 5, 6, 8 );
254 P2( C, D, E, A, B, 1, 12, 2, 13 );
255 P2( B, C, D, E, A, 3, 13, 13, 6 );
256 P2( A, B, C, D, E, 8, 14, 14, 5 );
257 P2( E, A, B, C, D, 11, 11, 0, 15 );
258 P2( D, E, A, B, C, 6, 8, 3, 13 );
259 P2( C, D, E, A, B, 15, 5, 9, 11 );
260 P2( B, C, D, E, A, 13, 6, 11, 11 );
261#undef F
262#undef K
263#undef Fp
264#undef Kp
265
266 C = ctx->state[1] + C + Dp;
267 ctx->state[1] = ctx->state[2] + D + Ep;
268 ctx->state[2] = ctx->state[3] + E + Ap;
269 ctx->state[3] = ctx->state[4] + A + Bp;
270 ctx->state[4] = ctx->state[0] + B + Cp;
271 ctx->state[0] = C;
272}
273
274/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100275 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100276 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100277void ripemd160_update( ripemd160_context *ctx,
278 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100279{
280 size_t fill;
281 uint32_t left;
282
283 if( ilen <= 0 )
284 return;
285
286 left = ctx->total[0] & 0x3F;
287 fill = 64 - left;
288
289 ctx->total[0] += (uint32_t) ilen;
290 ctx->total[0] &= 0xFFFFFFFF;
291
292 if( ctx->total[0] < (uint32_t) ilen )
293 ctx->total[1]++;
294
295 if( left && ilen >= fill )
296 {
297 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker61b699e2014-01-22 13:35:29 +0100298 ripemd160_process( ctx, ctx->buffer );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100299 input += fill;
300 ilen -= fill;
301 left = 0;
302 }
303
304 while( ilen >= 64 )
305 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100306 ripemd160_process( ctx, input );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100307 input += 64;
308 ilen -= 64;
309 }
310
311 if( ilen > 0 )
312 {
313 memcpy( (void *) (ctx->buffer + left), input, ilen );
314 }
315}
316
Paul Bakker61b699e2014-01-22 13:35:29 +0100317static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100318{
319 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
322 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
323};
324
325/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100326 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100327 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100328void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100329{
330 uint32_t last, padn;
331 uint32_t high, low;
332 unsigned char msglen[8];
333
334 high = ( ctx->total[0] >> 29 )
335 | ( ctx->total[1] << 3 );
336 low = ( ctx->total[0] << 3 );
337
338 PUT_UINT32_LE( low, msglen, 0 );
339 PUT_UINT32_LE( high, msglen, 4 );
340
341 last = ctx->total[0] & 0x3F;
342 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
343
Paul Bakker61b699e2014-01-22 13:35:29 +0100344 ripemd160_update( ctx, ripemd160_padding, padn );
345 ripemd160_update( ctx, msglen, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100346
347 PUT_UINT32_LE( ctx->state[0], output, 0 );
348 PUT_UINT32_LE( ctx->state[1], output, 4 );
349 PUT_UINT32_LE( ctx->state[2], output, 8 );
350 PUT_UINT32_LE( ctx->state[3], output, 12 );
351 PUT_UINT32_LE( ctx->state[4], output, 16 );
352}
353
354/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100355 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100356 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100357void ripemd160( const unsigned char *input, size_t ilen,
358 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100359{
Paul Bakker61b699e2014-01-22 13:35:29 +0100360 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361
Paul Bakker61b699e2014-01-22 13:35:29 +0100362 ripemd160_starts( &ctx );
363 ripemd160_update( &ctx, input, ilen );
364 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100365
Paul Bakker61b699e2014-01-22 13:35:29 +0100366 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100367}
368
369#if defined(POLARSSL_FS_IO)
370/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100371 * output = RIPEMD-160( file contents )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100373int ripemd160_file( const char *path, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100374{
375 FILE *f;
376 size_t n;
Paul Bakker61b699e2014-01-22 13:35:29 +0100377 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100378 unsigned char buf[1024];
379
380 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker61b699e2014-01-22 13:35:29 +0100381 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100382
Paul Bakker61b699e2014-01-22 13:35:29 +0100383 ripemd160_starts( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100384
385 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100386 ripemd160_update( &ctx, buf, n );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100387
Paul Bakker61b699e2014-01-22 13:35:29 +0100388 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100389
Paul Bakker61b699e2014-01-22 13:35:29 +0100390 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100391
392 if( ferror( f ) != 0 )
393 {
394 fclose( f );
Paul Bakker61b699e2014-01-22 13:35:29 +0100395 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100396 }
397
398 fclose( f );
399 return( 0 );
400}
401#endif /* POLARSSL_FS_IO */
402
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100403/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100404 * RIPEMD-160 HMAC context setup
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100405 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100406void ripemd160_hmac_starts( ripemd160_context *ctx,
407 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100408{
409 size_t i;
410 unsigned char sum[20];
411
412 if( keylen > 64 )
413 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100414 ripemd160( key, keylen, sum );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100415 keylen = 20;
416 key = sum;
417 }
418
419 memset( ctx->ipad, 0x36, 64 );
420 memset( ctx->opad, 0x5C, 64 );
421
422 for( i = 0; i < keylen; i++ )
423 {
424 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
425 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
426 }
427
Paul Bakker61b699e2014-01-22 13:35:29 +0100428 ripemd160_starts( ctx );
429 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100430
431 memset( sum, 0, sizeof( sum ) );
432}
433
434/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100435 * RIPEMD-160 HMAC process buffer
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100436 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100437void ripemd160_hmac_update( ripemd160_context *ctx,
438 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100439{
Paul Bakker61b699e2014-01-22 13:35:29 +0100440 ripemd160_update( ctx, input, ilen );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100441}
442
443/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100444 * RIPEMD-160 HMAC final digest
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100445 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100446void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100447{
448 unsigned char tmpbuf[20];
449
Paul Bakker61b699e2014-01-22 13:35:29 +0100450 ripemd160_finish( ctx, tmpbuf );
451 ripemd160_starts( ctx );
452 ripemd160_update( ctx, ctx->opad, 64 );
453 ripemd160_update( ctx, tmpbuf, 20 );
454 ripemd160_finish( ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100455
456 memset( tmpbuf, 0, sizeof( tmpbuf ) );
457}
458
459/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100460 * RIPEMD-160 HMAC context reset
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100461 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100462void ripemd160_hmac_reset( ripemd160_context *ctx )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100463{
Paul Bakker61b699e2014-01-22 13:35:29 +0100464 ripemd160_starts( ctx );
465 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100466}
467
468/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100469 * output = HMAC-RIPEMD-160( hmac key, input buffer )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100470 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100471void ripemd160_hmac( const unsigned char *key, size_t keylen,
472 const unsigned char *input, size_t ilen,
473 unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100474{
Paul Bakker61b699e2014-01-22 13:35:29 +0100475 ripemd160_context ctx;
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100476
Paul Bakker61b699e2014-01-22 13:35:29 +0100477 ripemd160_hmac_starts( &ctx, key, keylen );
478 ripemd160_hmac_update( &ctx, input, ilen );
479 ripemd160_hmac_finish( &ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100480
Paul Bakker61b699e2014-01-22 13:35:29 +0100481 memset( &ctx, 0, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100482}
483
484
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485#if defined(POLARSSL_SELF_TEST)
486/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100487 * Test vectors from the RIPEMD-160 paper and
488 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100489 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100490#define TESTS 8
491#define KEYS 2
Paul Bakker61b699e2014-01-22 13:35:29 +0100492static const char *ripemd160_test_input[TESTS] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100493{
494 "",
495 "a",
496 "abc",
497 "message digest",
498 "abcdefghijklmnopqrstuvwxyz",
499 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
500 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
501 "1234567890123456789012345678901234567890"
502 "1234567890123456789012345678901234567890",
503};
504
Paul Bakker61b699e2014-01-22 13:35:29 +0100505static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100506{
507 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
508 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
509 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
510 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
511 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
512 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
513 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
514 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
515 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
516 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
517 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
518 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
519 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
520 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
521 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
522 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
523};
524
Paul Bakker61b699e2014-01-22 13:35:29 +0100525static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100526{
527 {
528 { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b,
529 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 },
530 { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39,
531 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc },
532 { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7,
533 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 },
534 { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60,
535 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 },
536 { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9,
537 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb },
538 { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45,
539 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 },
540 { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b,
541 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 },
542 { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06,
543 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c },
544 },
545 {
546 { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa,
547 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 },
548 { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f,
549 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd },
550 { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c,
551 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 },
552 { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c,
553 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 },
554 { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed,
555 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 },
556 { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6,
557 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a },
558 { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f,
559 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 },
560 { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe,
561 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 },
562 },
563};
564
Paul Bakker61b699e2014-01-22 13:35:29 +0100565static const unsigned char ripemd160_test_key[KEYS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100566{
567 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
568 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 },
569 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
570 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 },
571};
572
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100573/*
574 * Checkup routine
575 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100576int ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100577{
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100578 int i, j;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100579 unsigned char output[20];
580
581 memset( output, 0, sizeof output );
582
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100583 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100584 {
585 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100586 polarssl_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100587
Paul Bakker61b699e2014-01-22 13:35:29 +0100588 ripemd160( (const unsigned char *) ripemd160_test_input[i],
589 strlen( ripemd160_test_input[i] ),
590 output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100591
Paul Bakker61b699e2014-01-22 13:35:29 +0100592 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100593 {
594 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100595 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100596
597 return( 1 );
598 }
599
600 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100601 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100602
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100603 for( j = 0; j < KEYS; j++ )
604 {
605 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100606 polarssl_printf( " HMAC-RIPEMD-160 test #%d, key #%d: ",
607 i + 1, j + 1 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100608
Paul Bakker61b699e2014-01-22 13:35:29 +0100609 ripemd160_hmac( ripemd160_test_key[j], 20,
610 (const unsigned char *) ripemd160_test_input[i],
611 strlen( ripemd160_test_input[i] ),
612 output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100613
Paul Bakker61b699e2014-01-22 13:35:29 +0100614 if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100615 {
616 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100617 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100618
619 return( 1 );
620 }
621
622 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100623 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100624 }
625
626 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100627 polarssl_printf( "\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100628 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100629
630 return( 0 );
631}
632
Paul Bakker9af723c2014-05-01 13:03:14 +0200633#endif /* POLARSSL_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100634
Paul Bakker9af723c2014-05-01 13:03:14 +0200635#endif /* POLARSSL_RIPEMD160_C */