blob: 83b2c2ce9fda54bd8a543b466ab1a3b4ecf97ed0 [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 *
Manuel Pégourié-Gonnard967a2a52015-01-22 14:28:16 +00006 * This file is part of mbed TLS (http://www.polarssl.org)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01007 * 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
Paul Bakker34617722014-06-13 17:20:13 +020079/* Implementation that should never be optimized out by the compiler */
80static void polarssl_zeroize( void *v, size_t n ) {
81 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
82}
83
Paul Bakker5b4af392014-06-26 12:09:34 +020084void ripemd160_init( ripemd160_context *ctx )
85{
86 memset( ctx, 0, sizeof( ripemd160_context ) );
87}
88
89void ripemd160_free( ripemd160_context *ctx )
90{
91 if( ctx == NULL )
92 return;
93
94 polarssl_zeroize( ctx, sizeof( ripemd160_context ) );
95}
96
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010097/*
Paul Bakker61b699e2014-01-22 13:35:29 +010098 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010099 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100100void ripemd160_starts( ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100101{
102 ctx->total[0] = 0;
103 ctx->total[1] = 0;
104
105 ctx->state[0] = 0x67452301;
106 ctx->state[1] = 0xEFCDAB89;
107 ctx->state[2] = 0x98BADCFE;
108 ctx->state[3] = 0x10325476;
109 ctx->state[4] = 0xC3D2E1F0;
110}
111
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100112/*
113 * Process one block
114 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100115void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100116{
117 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
118
119 GET_UINT32_LE( X[ 0], data, 0 );
120 GET_UINT32_LE( X[ 1], data, 4 );
121 GET_UINT32_LE( X[ 2], data, 8 );
122 GET_UINT32_LE( X[ 3], data, 12 );
123 GET_UINT32_LE( X[ 4], data, 16 );
124 GET_UINT32_LE( X[ 5], data, 20 );
125 GET_UINT32_LE( X[ 6], data, 24 );
126 GET_UINT32_LE( X[ 7], data, 28 );
127 GET_UINT32_LE( X[ 8], data, 32 );
128 GET_UINT32_LE( X[ 9], data, 36 );
129 GET_UINT32_LE( X[10], data, 40 );
130 GET_UINT32_LE( X[11], data, 44 );
131 GET_UINT32_LE( X[12], data, 48 );
132 GET_UINT32_LE( X[13], data, 52 );
133 GET_UINT32_LE( X[14], data, 56 );
134 GET_UINT32_LE( X[15], data, 60 );
135
136 A = Ap = ctx->state[0];
137 B = Bp = ctx->state[1];
138 C = Cp = ctx->state[2];
139 D = Dp = ctx->state[3];
140 E = Ep = ctx->state[4];
141
142#define F1( x, y, z ) ( x ^ y ^ z )
143#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
144#define F3( x, y, z ) ( ( x | ~y ) ^ z )
145#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
146#define F5( x, y, z ) ( x ^ ( y | ~z ) )
147
148#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
149
150#define P( a, b, c, d, e, r, s, f, k ) \
151 a += f( b, c, d ) + X[r] + k; \
152 a = S( a, s ) + e; \
153 c = S( c, 10 );
154
155#define P2( a, b, c, d, e, r, s, rp, sp ) \
156 P( a, b, c, d, e, r, s, F, K ); \
157 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
158
159#define F F1
160#define K 0x00000000
161#define Fp F5
162#define Kp 0x50A28BE6
163 P2( A, B, C, D, E, 0, 11, 5, 8 );
164 P2( E, A, B, C, D, 1, 14, 14, 9 );
165 P2( D, E, A, B, C, 2, 15, 7, 9 );
166 P2( C, D, E, A, B, 3, 12, 0, 11 );
167 P2( B, C, D, E, A, 4, 5, 9, 13 );
168 P2( A, B, C, D, E, 5, 8, 2, 15 );
169 P2( E, A, B, C, D, 6, 7, 11, 15 );
170 P2( D, E, A, B, C, 7, 9, 4, 5 );
171 P2( C, D, E, A, B, 8, 11, 13, 7 );
172 P2( B, C, D, E, A, 9, 13, 6, 7 );
173 P2( A, B, C, D, E, 10, 14, 15, 8 );
174 P2( E, A, B, C, D, 11, 15, 8, 11 );
175 P2( D, E, A, B, C, 12, 6, 1, 14 );
176 P2( C, D, E, A, B, 13, 7, 10, 14 );
177 P2( B, C, D, E, A, 14, 9, 3, 12 );
178 P2( A, B, C, D, E, 15, 8, 12, 6 );
179#undef F
180#undef K
181#undef Fp
182#undef Kp
183
184#define F F2
185#define K 0x5A827999
186#define Fp F4
187#define Kp 0x5C4DD124
188 P2( E, A, B, C, D, 7, 7, 6, 9 );
189 P2( D, E, A, B, C, 4, 6, 11, 13 );
190 P2( C, D, E, A, B, 13, 8, 3, 15 );
191 P2( B, C, D, E, A, 1, 13, 7, 7 );
192 P2( A, B, C, D, E, 10, 11, 0, 12 );
193 P2( E, A, B, C, D, 6, 9, 13, 8 );
194 P2( D, E, A, B, C, 15, 7, 5, 9 );
195 P2( C, D, E, A, B, 3, 15, 10, 11 );
196 P2( B, C, D, E, A, 12, 7, 14, 7 );
197 P2( A, B, C, D, E, 0, 12, 15, 7 );
198 P2( E, A, B, C, D, 9, 15, 8, 12 );
199 P2( D, E, A, B, C, 5, 9, 12, 7 );
200 P2( C, D, E, A, B, 2, 11, 4, 6 );
201 P2( B, C, D, E, A, 14, 7, 9, 15 );
202 P2( A, B, C, D, E, 11, 13, 1, 13 );
203 P2( E, A, B, C, D, 8, 12, 2, 11 );
204#undef F
205#undef K
206#undef Fp
207#undef Kp
208
209#define F F3
210#define K 0x6ED9EBA1
211#define Fp F3
212#define Kp 0x6D703EF3
213 P2( D, E, A, B, C, 3, 11, 15, 9 );
214 P2( C, D, E, A, B, 10, 13, 5, 7 );
215 P2( B, C, D, E, A, 14, 6, 1, 15 );
216 P2( A, B, C, D, E, 4, 7, 3, 11 );
217 P2( E, A, B, C, D, 9, 14, 7, 8 );
218 P2( D, E, A, B, C, 15, 9, 14, 6 );
219 P2( C, D, E, A, B, 8, 13, 6, 6 );
220 P2( B, C, D, E, A, 1, 15, 9, 14 );
221 P2( A, B, C, D, E, 2, 14, 11, 12 );
222 P2( E, A, B, C, D, 7, 8, 8, 13 );
223 P2( D, E, A, B, C, 0, 13, 12, 5 );
224 P2( C, D, E, A, B, 6, 6, 2, 14 );
225 P2( B, C, D, E, A, 13, 5, 10, 13 );
226 P2( A, B, C, D, E, 11, 12, 0, 13 );
227 P2( E, A, B, C, D, 5, 7, 4, 7 );
228 P2( D, E, A, B, C, 12, 5, 13, 5 );
229#undef F
230#undef K
231#undef Fp
232#undef Kp
233
234#define F F4
235#define K 0x8F1BBCDC
236#define Fp F2
237#define Kp 0x7A6D76E9
238 P2( C, D, E, A, B, 1, 11, 8, 15 );
239 P2( B, C, D, E, A, 9, 12, 6, 5 );
240 P2( A, B, C, D, E, 11, 14, 4, 8 );
241 P2( E, A, B, C, D, 10, 15, 1, 11 );
242 P2( D, E, A, B, C, 0, 14, 3, 14 );
243 P2( C, D, E, A, B, 8, 15, 11, 14 );
244 P2( B, C, D, E, A, 12, 9, 15, 6 );
245 P2( A, B, C, D, E, 4, 8, 0, 14 );
246 P2( E, A, B, C, D, 13, 9, 5, 6 );
247 P2( D, E, A, B, C, 3, 14, 12, 9 );
248 P2( C, D, E, A, B, 7, 5, 2, 12 );
249 P2( B, C, D, E, A, 15, 6, 13, 9 );
250 P2( A, B, C, D, E, 14, 8, 9, 12 );
251 P2( E, A, B, C, D, 5, 6, 7, 5 );
252 P2( D, E, A, B, C, 6, 5, 10, 15 );
253 P2( C, D, E, A, B, 2, 12, 14, 8 );
254#undef F
255#undef K
256#undef Fp
257#undef Kp
258
259#define F F5
260#define K 0xA953FD4E
261#define Fp F1
262#define Kp 0x00000000
263 P2( B, C, D, E, A, 4, 9, 12, 8 );
264 P2( A, B, C, D, E, 0, 15, 15, 5 );
265 P2( E, A, B, C, D, 5, 5, 10, 12 );
266 P2( D, E, A, B, C, 9, 11, 4, 9 );
267 P2( C, D, E, A, B, 7, 6, 1, 12 );
268 P2( B, C, D, E, A, 12, 8, 5, 5 );
269 P2( A, B, C, D, E, 2, 13, 8, 14 );
270 P2( E, A, B, C, D, 10, 12, 7, 6 );
271 P2( D, E, A, B, C, 14, 5, 6, 8 );
272 P2( C, D, E, A, B, 1, 12, 2, 13 );
273 P2( B, C, D, E, A, 3, 13, 13, 6 );
274 P2( A, B, C, D, E, 8, 14, 14, 5 );
275 P2( E, A, B, C, D, 11, 11, 0, 15 );
276 P2( D, E, A, B, C, 6, 8, 3, 13 );
277 P2( C, D, E, A, B, 15, 5, 9, 11 );
278 P2( B, C, D, E, A, 13, 6, 11, 11 );
279#undef F
280#undef K
281#undef Fp
282#undef Kp
283
284 C = ctx->state[1] + C + Dp;
285 ctx->state[1] = ctx->state[2] + D + Ep;
286 ctx->state[2] = ctx->state[3] + E + Ap;
287 ctx->state[3] = ctx->state[4] + A + Bp;
288 ctx->state[4] = ctx->state[0] + B + Cp;
289 ctx->state[0] = C;
290}
291
292/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100293 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100294 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100295void ripemd160_update( ripemd160_context *ctx,
296 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297{
298 size_t fill;
299 uint32_t left;
300
Brian White12895d12014-04-11 11:29:42 -0400301 if( ilen == 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100302 return;
303
304 left = ctx->total[0] & 0x3F;
305 fill = 64 - left;
306
307 ctx->total[0] += (uint32_t) ilen;
308 ctx->total[0] &= 0xFFFFFFFF;
309
310 if( ctx->total[0] < (uint32_t) ilen )
311 ctx->total[1]++;
312
313 if( left && ilen >= fill )
314 {
315 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker61b699e2014-01-22 13:35:29 +0100316 ripemd160_process( ctx, ctx->buffer );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100317 input += fill;
318 ilen -= fill;
319 left = 0;
320 }
321
322 while( ilen >= 64 )
323 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100324 ripemd160_process( ctx, input );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100325 input += 64;
326 ilen -= 64;
327 }
328
329 if( ilen > 0 )
330 {
331 memcpy( (void *) (ctx->buffer + left), input, ilen );
332 }
333}
334
Paul Bakker61b699e2014-01-22 13:35:29 +0100335static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100336{
337 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
339 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
341};
342
343/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100344 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100345 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100346void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100347{
348 uint32_t last, padn;
349 uint32_t high, low;
350 unsigned char msglen[8];
351
352 high = ( ctx->total[0] >> 29 )
353 | ( ctx->total[1] << 3 );
354 low = ( ctx->total[0] << 3 );
355
356 PUT_UINT32_LE( low, msglen, 0 );
357 PUT_UINT32_LE( high, msglen, 4 );
358
359 last = ctx->total[0] & 0x3F;
360 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
361
Paul Bakker61b699e2014-01-22 13:35:29 +0100362 ripemd160_update( ctx, ripemd160_padding, padn );
363 ripemd160_update( ctx, msglen, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364
365 PUT_UINT32_LE( ctx->state[0], output, 0 );
366 PUT_UINT32_LE( ctx->state[1], output, 4 );
367 PUT_UINT32_LE( ctx->state[2], output, 8 );
368 PUT_UINT32_LE( ctx->state[3], output, 12 );
369 PUT_UINT32_LE( ctx->state[4], output, 16 );
370}
371
372/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100373 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100374 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100375void ripemd160( const unsigned char *input, size_t ilen,
376 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100377{
Paul Bakker61b699e2014-01-22 13:35:29 +0100378 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100379
Paul Bakker5b4af392014-06-26 12:09:34 +0200380 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100381 ripemd160_starts( &ctx );
382 ripemd160_update( &ctx, input, ilen );
383 ripemd160_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200384 ripemd160_free( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100385}
386
387#if defined(POLARSSL_FS_IO)
388/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100389 * output = RIPEMD-160( file contents )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100390 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100391int ripemd160_file( const char *path, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100392{
393 FILE *f;
394 size_t n;
Paul Bakker61b699e2014-01-22 13:35:29 +0100395 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100396 unsigned char buf[1024];
397
398 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker61b699e2014-01-22 13:35:29 +0100399 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100400
Paul Bakker5b4af392014-06-26 12:09:34 +0200401 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100402 ripemd160_starts( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100403
404 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100405 ripemd160_update( &ctx, buf, n );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406
Paul Bakker61b699e2014-01-22 13:35:29 +0100407 ripemd160_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200408 ripemd160_free( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100409
410 if( ferror( f ) != 0 )
411 {
412 fclose( f );
Paul Bakker61b699e2014-01-22 13:35:29 +0100413 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100414 }
415
416 fclose( f );
417 return( 0 );
418}
419#endif /* POLARSSL_FS_IO */
420
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100421/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100422 * RIPEMD-160 HMAC context setup
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100423 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100424void ripemd160_hmac_starts( ripemd160_context *ctx,
425 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100426{
427 size_t i;
428 unsigned char sum[20];
429
430 if( keylen > 64 )
431 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100432 ripemd160( key, keylen, sum );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100433 keylen = 20;
434 key = sum;
435 }
436
437 memset( ctx->ipad, 0x36, 64 );
438 memset( ctx->opad, 0x5C, 64 );
439
440 for( i = 0; i < keylen; i++ )
441 {
442 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
443 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
444 }
445
Paul Bakker61b699e2014-01-22 13:35:29 +0100446 ripemd160_starts( ctx );
447 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100448
Paul Bakker34617722014-06-13 17:20:13 +0200449 polarssl_zeroize( sum, sizeof( sum ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100450}
451
452/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100453 * RIPEMD-160 HMAC process buffer
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100454 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100455void ripemd160_hmac_update( ripemd160_context *ctx,
456 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100457{
Paul Bakker61b699e2014-01-22 13:35:29 +0100458 ripemd160_update( ctx, input, ilen );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100459}
460
461/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100462 * RIPEMD-160 HMAC final digest
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100463 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100464void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100465{
466 unsigned char tmpbuf[20];
467
Paul Bakker61b699e2014-01-22 13:35:29 +0100468 ripemd160_finish( ctx, tmpbuf );
469 ripemd160_starts( ctx );
470 ripemd160_update( ctx, ctx->opad, 64 );
471 ripemd160_update( ctx, tmpbuf, 20 );
472 ripemd160_finish( ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100473
Paul Bakker34617722014-06-13 17:20:13 +0200474 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100475}
476
477/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100478 * RIPEMD-160 HMAC context reset
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100479 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100480void ripemd160_hmac_reset( ripemd160_context *ctx )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100481{
Paul Bakker61b699e2014-01-22 13:35:29 +0100482 ripemd160_starts( ctx );
483 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100484}
485
486/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100487 * output = HMAC-RIPEMD-160( hmac key, input buffer )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100488 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100489void ripemd160_hmac( const unsigned char *key, size_t keylen,
490 const unsigned char *input, size_t ilen,
491 unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100492{
Paul Bakker61b699e2014-01-22 13:35:29 +0100493 ripemd160_context ctx;
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100494
Paul Bakker5b4af392014-06-26 12:09:34 +0200495 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100496 ripemd160_hmac_starts( &ctx, key, keylen );
497 ripemd160_hmac_update( &ctx, input, ilen );
498 ripemd160_hmac_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200499 ripemd160_free( &ctx );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100500}
501
502
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100503#if defined(POLARSSL_SELF_TEST)
504/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100505 * Test vectors from the RIPEMD-160 paper and
506 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100507 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100508#define TESTS 8
509#define KEYS 2
Paul Bakker61b699e2014-01-22 13:35:29 +0100510static const char *ripemd160_test_input[TESTS] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100511{
512 "",
513 "a",
514 "abc",
515 "message digest",
516 "abcdefghijklmnopqrstuvwxyz",
517 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
518 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
519 "1234567890123456789012345678901234567890"
520 "1234567890123456789012345678901234567890",
521};
522
Paul Bakker61b699e2014-01-22 13:35:29 +0100523static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100524{
525 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
526 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
527 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
528 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
529 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
530 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
531 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
532 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
533 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
534 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
535 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
536 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
537 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
538 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
539 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
540 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
541};
542
Paul Bakker61b699e2014-01-22 13:35:29 +0100543static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100544{
545 {
546 { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b,
547 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 },
548 { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39,
549 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc },
550 { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7,
551 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 },
552 { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60,
553 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 },
554 { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9,
555 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb },
556 { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45,
557 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 },
558 { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b,
559 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 },
560 { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06,
561 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c },
562 },
563 {
564 { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa,
565 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 },
566 { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f,
567 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd },
568 { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c,
569 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 },
570 { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c,
571 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 },
572 { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed,
573 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 },
574 { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6,
575 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a },
576 { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f,
577 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 },
578 { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe,
579 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 },
580 },
581};
582
Paul Bakker61b699e2014-01-22 13:35:29 +0100583static const unsigned char ripemd160_test_key[KEYS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100584{
585 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
586 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 },
587 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
588 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 },
589};
590
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100591/*
592 * Checkup routine
593 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100594int ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100595{
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100596 int i, j;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100597 unsigned char output[20];
598
599 memset( output, 0, sizeof output );
600
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100601 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100602 {
603 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100604 polarssl_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100605
Paul Bakker61b699e2014-01-22 13:35:29 +0100606 ripemd160( (const unsigned char *) ripemd160_test_input[i],
607 strlen( ripemd160_test_input[i] ),
608 output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100609
Paul Bakker61b699e2014-01-22 13:35:29 +0100610 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100611 {
612 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100613 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +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é-Gonnardcab4a882014-01-17 12:42:35 +0100620
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100621 for( j = 0; j < KEYS; j++ )
622 {
623 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100624 polarssl_printf( " HMAC-RIPEMD-160 test #%d, key #%d: ",
625 i + 1, j + 1 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100626
Paul Bakker61b699e2014-01-22 13:35:29 +0100627 ripemd160_hmac( ripemd160_test_key[j], 20,
628 (const unsigned char *) ripemd160_test_input[i],
629 strlen( ripemd160_test_input[i] ),
630 output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100631
Paul Bakker61b699e2014-01-22 13:35:29 +0100632 if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100633 {
634 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100635 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100636
637 return( 1 );
638 }
639
640 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100641 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100642 }
643
644 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100645 polarssl_printf( "\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100646 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100647
648 return( 0 );
649}
650
Paul Bakker9af723c2014-05-01 13:03:14 +0200651#endif /* POLARSSL_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100652
Paul Bakker9af723c2014-05-01 13:03:14 +0200653#endif /* POLARSSL_RIPEMD160_C */