blob: 7b5d02e2e53aa5e4fbc4cc998e704f7e5f7bfea0 [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2014-2014, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01007 *
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23/*
24 * The RIPEMD-160 algorithm was designed by RIPE in 1996
25 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
26 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
27 */
28
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020029#if !defined(POLARSSL_CONFIG_FILE)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010030#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#else
32#include POLARSSL_CONFIG_FILE
33#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010034
Paul Bakker61b699e2014-01-22 13:35:29 +010035#if defined(POLARSSL_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010036
Paul Bakker61b699e2014-01-22 13:35:29 +010037#include "polarssl/ripemd160.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
41#if defined(POLARSSL_FS_IO)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010042#include <stdio.h>
43#endif
44
45#if defined(POLARSSL_SELF_TEST)
Paul Bakker7dc4c442014-02-01 22:50:26 +010046#if defined(POLARSSL_PLATFORM_C)
47#include "polarssl/platform.h"
48#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Paul Bakker7dc4c442014-02-01 22:50:26 +010050#define polarssl_printf printf
Rich Evans00ab4702015-02-06 13:43:58 +000051#endif /* POLARSSL_PLATFORM_C */
52#endif /* POLARSSL_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010054/*
55 * 32-bit integer manipulation macros (little endian)
56 */
57#ifndef GET_UINT32_LE
58#define GET_UINT32_LE(n,b,i) \
59{ \
60 (n) = ( (uint32_t) (b)[(i) ] ) \
61 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
62 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
63 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
64}
65#endif
66
67#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000068#define PUT_UINT32_LE(n,b,i) \
69{ \
70 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
71 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
72 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
73 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010074}
75#endif
76
Paul Bakker34617722014-06-13 17:20:13 +020077/* Implementation that should never be optimized out by the compiler */
78static void polarssl_zeroize( void *v, size_t n ) {
79 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
80}
81
Paul Bakker5b4af392014-06-26 12:09:34 +020082void ripemd160_init( ripemd160_context *ctx )
83{
84 memset( ctx, 0, sizeof( ripemd160_context ) );
85}
86
87void ripemd160_free( ripemd160_context *ctx )
88{
89 if( ctx == NULL )
90 return;
91
92 polarssl_zeroize( ctx, sizeof( ripemd160_context ) );
93}
94
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010095/*
Paul Bakker61b699e2014-01-22 13:35:29 +010096 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010097 */
Paul Bakker61b699e2014-01-22 13:35:29 +010098void ripemd160_starts( ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010099{
100 ctx->total[0] = 0;
101 ctx->total[1] = 0;
102
103 ctx->state[0] = 0x67452301;
104 ctx->state[1] = 0xEFCDAB89;
105 ctx->state[2] = 0x98BADCFE;
106 ctx->state[3] = 0x10325476;
107 ctx->state[4] = 0xC3D2E1F0;
108}
109
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100110/*
111 * Process one block
112 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100113void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100114{
115 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
116
117 GET_UINT32_LE( X[ 0], data, 0 );
118 GET_UINT32_LE( X[ 1], data, 4 );
119 GET_UINT32_LE( X[ 2], data, 8 );
120 GET_UINT32_LE( X[ 3], data, 12 );
121 GET_UINT32_LE( X[ 4], data, 16 );
122 GET_UINT32_LE( X[ 5], data, 20 );
123 GET_UINT32_LE( X[ 6], data, 24 );
124 GET_UINT32_LE( X[ 7], data, 28 );
125 GET_UINT32_LE( X[ 8], data, 32 );
126 GET_UINT32_LE( X[ 9], data, 36 );
127 GET_UINT32_LE( X[10], data, 40 );
128 GET_UINT32_LE( X[11], data, 44 );
129 GET_UINT32_LE( X[12], data, 48 );
130 GET_UINT32_LE( X[13], data, 52 );
131 GET_UINT32_LE( X[14], data, 56 );
132 GET_UINT32_LE( X[15], data, 60 );
133
134 A = Ap = ctx->state[0];
135 B = Bp = ctx->state[1];
136 C = Cp = ctx->state[2];
137 D = Dp = ctx->state[3];
138 E = Ep = ctx->state[4];
139
140#define F1( x, y, z ) ( x ^ y ^ z )
141#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
142#define F3( x, y, z ) ( ( x | ~y ) ^ z )
143#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
144#define F5( x, y, z ) ( x ^ ( y | ~z ) )
145
146#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
147
148#define P( a, b, c, d, e, r, s, f, k ) \
149 a += f( b, c, d ) + X[r] + k; \
150 a = S( a, s ) + e; \
151 c = S( c, 10 );
152
153#define P2( a, b, c, d, e, r, s, rp, sp ) \
154 P( a, b, c, d, e, r, s, F, K ); \
155 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
156
157#define F F1
158#define K 0x00000000
159#define Fp F5
160#define Kp 0x50A28BE6
161 P2( A, B, C, D, E, 0, 11, 5, 8 );
162 P2( E, A, B, C, D, 1, 14, 14, 9 );
163 P2( D, E, A, B, C, 2, 15, 7, 9 );
164 P2( C, D, E, A, B, 3, 12, 0, 11 );
165 P2( B, C, D, E, A, 4, 5, 9, 13 );
166 P2( A, B, C, D, E, 5, 8, 2, 15 );
167 P2( E, A, B, C, D, 6, 7, 11, 15 );
168 P2( D, E, A, B, C, 7, 9, 4, 5 );
169 P2( C, D, E, A, B, 8, 11, 13, 7 );
170 P2( B, C, D, E, A, 9, 13, 6, 7 );
171 P2( A, B, C, D, E, 10, 14, 15, 8 );
172 P2( E, A, B, C, D, 11, 15, 8, 11 );
173 P2( D, E, A, B, C, 12, 6, 1, 14 );
174 P2( C, D, E, A, B, 13, 7, 10, 14 );
175 P2( B, C, D, E, A, 14, 9, 3, 12 );
176 P2( A, B, C, D, E, 15, 8, 12, 6 );
177#undef F
178#undef K
179#undef Fp
180#undef Kp
181
182#define F F2
183#define K 0x5A827999
184#define Fp F4
185#define Kp 0x5C4DD124
186 P2( E, A, B, C, D, 7, 7, 6, 9 );
187 P2( D, E, A, B, C, 4, 6, 11, 13 );
188 P2( C, D, E, A, B, 13, 8, 3, 15 );
189 P2( B, C, D, E, A, 1, 13, 7, 7 );
190 P2( A, B, C, D, E, 10, 11, 0, 12 );
191 P2( E, A, B, C, D, 6, 9, 13, 8 );
192 P2( D, E, A, B, C, 15, 7, 5, 9 );
193 P2( C, D, E, A, B, 3, 15, 10, 11 );
194 P2( B, C, D, E, A, 12, 7, 14, 7 );
195 P2( A, B, C, D, E, 0, 12, 15, 7 );
196 P2( E, A, B, C, D, 9, 15, 8, 12 );
197 P2( D, E, A, B, C, 5, 9, 12, 7 );
198 P2( C, D, E, A, B, 2, 11, 4, 6 );
199 P2( B, C, D, E, A, 14, 7, 9, 15 );
200 P2( A, B, C, D, E, 11, 13, 1, 13 );
201 P2( E, A, B, C, D, 8, 12, 2, 11 );
202#undef F
203#undef K
204#undef Fp
205#undef Kp
206
207#define F F3
208#define K 0x6ED9EBA1
209#define Fp F3
210#define Kp 0x6D703EF3
211 P2( D, E, A, B, C, 3, 11, 15, 9 );
212 P2( C, D, E, A, B, 10, 13, 5, 7 );
213 P2( B, C, D, E, A, 14, 6, 1, 15 );
214 P2( A, B, C, D, E, 4, 7, 3, 11 );
215 P2( E, A, B, C, D, 9, 14, 7, 8 );
216 P2( D, E, A, B, C, 15, 9, 14, 6 );
217 P2( C, D, E, A, B, 8, 13, 6, 6 );
218 P2( B, C, D, E, A, 1, 15, 9, 14 );
219 P2( A, B, C, D, E, 2, 14, 11, 12 );
220 P2( E, A, B, C, D, 7, 8, 8, 13 );
221 P2( D, E, A, B, C, 0, 13, 12, 5 );
222 P2( C, D, E, A, B, 6, 6, 2, 14 );
223 P2( B, C, D, E, A, 13, 5, 10, 13 );
224 P2( A, B, C, D, E, 11, 12, 0, 13 );
225 P2( E, A, B, C, D, 5, 7, 4, 7 );
226 P2( D, E, A, B, C, 12, 5, 13, 5 );
227#undef F
228#undef K
229#undef Fp
230#undef Kp
231
232#define F F4
233#define K 0x8F1BBCDC
234#define Fp F2
235#define Kp 0x7A6D76E9
236 P2( C, D, E, A, B, 1, 11, 8, 15 );
237 P2( B, C, D, E, A, 9, 12, 6, 5 );
238 P2( A, B, C, D, E, 11, 14, 4, 8 );
239 P2( E, A, B, C, D, 10, 15, 1, 11 );
240 P2( D, E, A, B, C, 0, 14, 3, 14 );
241 P2( C, D, E, A, B, 8, 15, 11, 14 );
242 P2( B, C, D, E, A, 12, 9, 15, 6 );
243 P2( A, B, C, D, E, 4, 8, 0, 14 );
244 P2( E, A, B, C, D, 13, 9, 5, 6 );
245 P2( D, E, A, B, C, 3, 14, 12, 9 );
246 P2( C, D, E, A, B, 7, 5, 2, 12 );
247 P2( B, C, D, E, A, 15, 6, 13, 9 );
248 P2( A, B, C, D, E, 14, 8, 9, 12 );
249 P2( E, A, B, C, D, 5, 6, 7, 5 );
250 P2( D, E, A, B, C, 6, 5, 10, 15 );
251 P2( C, D, E, A, B, 2, 12, 14, 8 );
252#undef F
253#undef K
254#undef Fp
255#undef Kp
256
257#define F F5
258#define K 0xA953FD4E
259#define Fp F1
260#define Kp 0x00000000
261 P2( B, C, D, E, A, 4, 9, 12, 8 );
262 P2( A, B, C, D, E, 0, 15, 15, 5 );
263 P2( E, A, B, C, D, 5, 5, 10, 12 );
264 P2( D, E, A, B, C, 9, 11, 4, 9 );
265 P2( C, D, E, A, B, 7, 6, 1, 12 );
266 P2( B, C, D, E, A, 12, 8, 5, 5 );
267 P2( A, B, C, D, E, 2, 13, 8, 14 );
268 P2( E, A, B, C, D, 10, 12, 7, 6 );
269 P2( D, E, A, B, C, 14, 5, 6, 8 );
270 P2( C, D, E, A, B, 1, 12, 2, 13 );
271 P2( B, C, D, E, A, 3, 13, 13, 6 );
272 P2( A, B, C, D, E, 8, 14, 14, 5 );
273 P2( E, A, B, C, D, 11, 11, 0, 15 );
274 P2( D, E, A, B, C, 6, 8, 3, 13 );
275 P2( C, D, E, A, B, 15, 5, 9, 11 );
276 P2( B, C, D, E, A, 13, 6, 11, 11 );
277#undef F
278#undef K
279#undef Fp
280#undef Kp
281
282 C = ctx->state[1] + C + Dp;
283 ctx->state[1] = ctx->state[2] + D + Ep;
284 ctx->state[2] = ctx->state[3] + E + Ap;
285 ctx->state[3] = ctx->state[4] + A + Bp;
286 ctx->state[4] = ctx->state[0] + B + Cp;
287 ctx->state[0] = C;
288}
289
290/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100291 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100292 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100293void ripemd160_update( ripemd160_context *ctx,
294 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100295{
296 size_t fill;
297 uint32_t left;
298
Brian White12895d12014-04-11 11:29:42 -0400299 if( ilen == 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100300 return;
301
302 left = ctx->total[0] & 0x3F;
303 fill = 64 - left;
304
305 ctx->total[0] += (uint32_t) ilen;
306 ctx->total[0] &= 0xFFFFFFFF;
307
308 if( ctx->total[0] < (uint32_t) ilen )
309 ctx->total[1]++;
310
311 if( left && ilen >= fill )
312 {
313 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker61b699e2014-01-22 13:35:29 +0100314 ripemd160_process( ctx, ctx->buffer );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100315 input += fill;
316 ilen -= fill;
317 left = 0;
318 }
319
320 while( ilen >= 64 )
321 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100322 ripemd160_process( ctx, input );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100323 input += 64;
324 ilen -= 64;
325 }
326
327 if( ilen > 0 )
328 {
329 memcpy( (void *) (ctx->buffer + left), input, ilen );
330 }
331}
332
Paul Bakker61b699e2014-01-22 13:35:29 +0100333static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100334{
335 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
339};
340
341/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100342 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100343 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100344void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100345{
346 uint32_t last, padn;
347 uint32_t high, low;
348 unsigned char msglen[8];
349
350 high = ( ctx->total[0] >> 29 )
351 | ( ctx->total[1] << 3 );
352 low = ( ctx->total[0] << 3 );
353
354 PUT_UINT32_LE( low, msglen, 0 );
355 PUT_UINT32_LE( high, msglen, 4 );
356
357 last = ctx->total[0] & 0x3F;
358 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
359
Paul Bakker61b699e2014-01-22 13:35:29 +0100360 ripemd160_update( ctx, ripemd160_padding, padn );
361 ripemd160_update( ctx, msglen, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100362
363 PUT_UINT32_LE( ctx->state[0], output, 0 );
364 PUT_UINT32_LE( ctx->state[1], output, 4 );
365 PUT_UINT32_LE( ctx->state[2], output, 8 );
366 PUT_UINT32_LE( ctx->state[3], output, 12 );
367 PUT_UINT32_LE( ctx->state[4], output, 16 );
368}
369
370/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100371 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100373void ripemd160( const unsigned char *input, size_t ilen,
374 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100375{
Paul Bakker61b699e2014-01-22 13:35:29 +0100376 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100377
Paul Bakker5b4af392014-06-26 12:09:34 +0200378 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100379 ripemd160_starts( &ctx );
380 ripemd160_update( &ctx, input, ilen );
381 ripemd160_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200382 ripemd160_free( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100383}
384
385#if defined(POLARSSL_FS_IO)
386/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100387 * output = RIPEMD-160( file contents )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100388 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100389int ripemd160_file( const char *path, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100390{
Andres Amaya Garcia3d98b972017-09-20 11:47:49 +0100391 int ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100392 FILE *f;
393 size_t n;
Paul Bakker61b699e2014-01-22 13:35:29 +0100394 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100395 unsigned char buf[1024];
396
397 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker61b699e2014-01-22 13:35:29 +0100398 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100399
Paul Bakker5b4af392014-06-26 12:09:34 +0200400 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100401 ripemd160_starts( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100402
403 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100404 ripemd160_update( &ctx, buf, n );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100405
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406 if( ferror( f ) != 0 )
Andres Amaya Garcia3d98b972017-09-20 11:47:49 +0100407 ret = POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR;
408 else
409 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100410
Andres Amaya Garcia3d98b972017-09-20 11:47:49 +0100411 ripemd160_free( &ctx );
412 polarssl_zeroize( buf, sizeof( buf ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100413 fclose( f );
Andres Amaya Garcia3d98b972017-09-20 11:47:49 +0100414
415 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100416}
417#endif /* POLARSSL_FS_IO */
418
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100419/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100420 * RIPEMD-160 HMAC context setup
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100421 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100422void ripemd160_hmac_starts( ripemd160_context *ctx,
423 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100424{
425 size_t i;
426 unsigned char sum[20];
427
428 if( keylen > 64 )
429 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100430 ripemd160( key, keylen, sum );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100431 keylen = 20;
432 key = sum;
433 }
434
435 memset( ctx->ipad, 0x36, 64 );
436 memset( ctx->opad, 0x5C, 64 );
437
438 for( i = 0; i < keylen; i++ )
439 {
440 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
441 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
442 }
443
Paul Bakker61b699e2014-01-22 13:35:29 +0100444 ripemd160_starts( ctx );
445 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100446
Paul Bakker34617722014-06-13 17:20:13 +0200447 polarssl_zeroize( sum, sizeof( sum ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100448}
449
450/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100451 * RIPEMD-160 HMAC process buffer
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100452 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100453void ripemd160_hmac_update( ripemd160_context *ctx,
454 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100455{
Paul Bakker61b699e2014-01-22 13:35:29 +0100456 ripemd160_update( ctx, input, ilen );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100457}
458
459/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100460 * RIPEMD-160 HMAC final digest
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100461 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100462void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100463{
464 unsigned char tmpbuf[20];
465
Paul Bakker61b699e2014-01-22 13:35:29 +0100466 ripemd160_finish( ctx, tmpbuf );
467 ripemd160_starts( ctx );
468 ripemd160_update( ctx, ctx->opad, 64 );
469 ripemd160_update( ctx, tmpbuf, 20 );
470 ripemd160_finish( ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100471
Paul Bakker34617722014-06-13 17:20:13 +0200472 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100473}
474
475/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100476 * RIPEMD-160 HMAC context reset
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100477 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100478void ripemd160_hmac_reset( ripemd160_context *ctx )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100479{
Paul Bakker61b699e2014-01-22 13:35:29 +0100480 ripemd160_starts( ctx );
481 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100482}
483
484/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100485 * output = HMAC-RIPEMD-160( hmac key, input buffer )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100486 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100487void ripemd160_hmac( const unsigned char *key, size_t keylen,
488 const unsigned char *input, size_t ilen,
489 unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100490{
Paul Bakker61b699e2014-01-22 13:35:29 +0100491 ripemd160_context ctx;
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100492
Paul Bakker5b4af392014-06-26 12:09:34 +0200493 ripemd160_init( &ctx );
Paul Bakker61b699e2014-01-22 13:35:29 +0100494 ripemd160_hmac_starts( &ctx, key, keylen );
495 ripemd160_hmac_update( &ctx, input, ilen );
496 ripemd160_hmac_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200497 ripemd160_free( &ctx );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100498}
499
500
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100501#if defined(POLARSSL_SELF_TEST)
502/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100503 * Test vectors from the RIPEMD-160 paper and
504 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100505 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100506#define TESTS 8
507#define KEYS 2
Paul Bakker61b699e2014-01-22 13:35:29 +0100508static const char *ripemd160_test_input[TESTS] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100509{
510 "",
511 "a",
512 "abc",
513 "message digest",
514 "abcdefghijklmnopqrstuvwxyz",
515 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
516 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
517 "1234567890123456789012345678901234567890"
518 "1234567890123456789012345678901234567890",
519};
520
Paul Bakker61b699e2014-01-22 13:35:29 +0100521static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100522{
523 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
524 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
525 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
526 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
527 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
528 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
529 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
530 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
531 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
532 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
533 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
534 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
535 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
536 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
537 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
538 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
539};
540
Paul Bakker61b699e2014-01-22 13:35:29 +0100541static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100542{
543 {
544 { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b,
545 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 },
546 { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39,
547 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc },
548 { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7,
549 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 },
550 { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60,
551 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 },
552 { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9,
553 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb },
554 { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45,
555 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 },
556 { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b,
557 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 },
558 { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06,
559 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c },
560 },
561 {
562 { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa,
563 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 },
564 { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f,
565 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd },
566 { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c,
567 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 },
568 { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c,
569 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 },
570 { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed,
571 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 },
572 { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6,
573 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a },
574 { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f,
575 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 },
576 { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe,
577 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 },
578 },
579};
580
Paul Bakker61b699e2014-01-22 13:35:29 +0100581static const unsigned char ripemd160_test_key[KEYS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100582{
583 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
584 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 },
585 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
586 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 },
587};
588
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100589/*
590 * Checkup routine
591 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100592int ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100593{
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100594 int i, j;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100595 unsigned char output[20];
596
597 memset( output, 0, sizeof output );
598
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100599 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100600 {
601 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100602 polarssl_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100603
Paul Bakker61b699e2014-01-22 13:35:29 +0100604 ripemd160( (const unsigned char *) ripemd160_test_input[i],
605 strlen( ripemd160_test_input[i] ),
606 output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100607
Paul Bakker61b699e2014-01-22 13:35:29 +0100608 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100609 {
610 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100611 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100612
613 return( 1 );
614 }
615
616 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100617 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100618
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100619 for( j = 0; j < KEYS; j++ )
620 {
621 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100622 polarssl_printf( " HMAC-RIPEMD-160 test #%d, key #%d: ",
623 i + 1, j + 1 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100624
Paul Bakker61b699e2014-01-22 13:35:29 +0100625 ripemd160_hmac( ripemd160_test_key[j], 20,
626 (const unsigned char *) ripemd160_test_input[i],
627 strlen( ripemd160_test_input[i] ),
628 output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100629
Paul Bakker61b699e2014-01-22 13:35:29 +0100630 if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100631 {
632 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100633 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100634
635 return( 1 );
636 }
637
638 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100639 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100640 }
641
642 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100643 polarssl_printf( "\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100644 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100645
646 return( 0 );
647}
648
Paul Bakker9af723c2014-05-01 13:03:14 +0200649#endif /* POLARSSL_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100650
Paul Bakker9af723c2014-05-01 13:03:14 +0200651#endif /* POLARSSL_RIPEMD160_C */