blob: 3c2a7e663ca586c2a97f2ba64fa8a36e67c3b537 [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
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
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010084/*
Paul Bakker61b699e2014-01-22 13:35:29 +010085 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010086 */
Paul Bakker61b699e2014-01-22 13:35:29 +010087void ripemd160_starts( ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010088{
89 ctx->total[0] = 0;
90 ctx->total[1] = 0;
91
92 ctx->state[0] = 0x67452301;
93 ctx->state[1] = 0xEFCDAB89;
94 ctx->state[2] = 0x98BADCFE;
95 ctx->state[3] = 0x10325476;
96 ctx->state[4] = 0xC3D2E1F0;
97}
98
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010099/*
100 * Process one block
101 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100102void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100103{
104 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
105
106 GET_UINT32_LE( X[ 0], data, 0 );
107 GET_UINT32_LE( X[ 1], data, 4 );
108 GET_UINT32_LE( X[ 2], data, 8 );
109 GET_UINT32_LE( X[ 3], data, 12 );
110 GET_UINT32_LE( X[ 4], data, 16 );
111 GET_UINT32_LE( X[ 5], data, 20 );
112 GET_UINT32_LE( X[ 6], data, 24 );
113 GET_UINT32_LE( X[ 7], data, 28 );
114 GET_UINT32_LE( X[ 8], data, 32 );
115 GET_UINT32_LE( X[ 9], data, 36 );
116 GET_UINT32_LE( X[10], data, 40 );
117 GET_UINT32_LE( X[11], data, 44 );
118 GET_UINT32_LE( X[12], data, 48 );
119 GET_UINT32_LE( X[13], data, 52 );
120 GET_UINT32_LE( X[14], data, 56 );
121 GET_UINT32_LE( X[15], data, 60 );
122
123 A = Ap = ctx->state[0];
124 B = Bp = ctx->state[1];
125 C = Cp = ctx->state[2];
126 D = Dp = ctx->state[3];
127 E = Ep = ctx->state[4];
128
129#define F1( x, y, z ) ( x ^ y ^ z )
130#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
131#define F3( x, y, z ) ( ( x | ~y ) ^ z )
132#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
133#define F5( x, y, z ) ( x ^ ( y | ~z ) )
134
135#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
136
137#define P( a, b, c, d, e, r, s, f, k ) \
138 a += f( b, c, d ) + X[r] + k; \
139 a = S( a, s ) + e; \
140 c = S( c, 10 );
141
142#define P2( a, b, c, d, e, r, s, rp, sp ) \
143 P( a, b, c, d, e, r, s, F, K ); \
144 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
145
146#define F F1
147#define K 0x00000000
148#define Fp F5
149#define Kp 0x50A28BE6
150 P2( A, B, C, D, E, 0, 11, 5, 8 );
151 P2( E, A, B, C, D, 1, 14, 14, 9 );
152 P2( D, E, A, B, C, 2, 15, 7, 9 );
153 P2( C, D, E, A, B, 3, 12, 0, 11 );
154 P2( B, C, D, E, A, 4, 5, 9, 13 );
155 P2( A, B, C, D, E, 5, 8, 2, 15 );
156 P2( E, A, B, C, D, 6, 7, 11, 15 );
157 P2( D, E, A, B, C, 7, 9, 4, 5 );
158 P2( C, D, E, A, B, 8, 11, 13, 7 );
159 P2( B, C, D, E, A, 9, 13, 6, 7 );
160 P2( A, B, C, D, E, 10, 14, 15, 8 );
161 P2( E, A, B, C, D, 11, 15, 8, 11 );
162 P2( D, E, A, B, C, 12, 6, 1, 14 );
163 P2( C, D, E, A, B, 13, 7, 10, 14 );
164 P2( B, C, D, E, A, 14, 9, 3, 12 );
165 P2( A, B, C, D, E, 15, 8, 12, 6 );
166#undef F
167#undef K
168#undef Fp
169#undef Kp
170
171#define F F2
172#define K 0x5A827999
173#define Fp F4
174#define Kp 0x5C4DD124
175 P2( E, A, B, C, D, 7, 7, 6, 9 );
176 P2( D, E, A, B, C, 4, 6, 11, 13 );
177 P2( C, D, E, A, B, 13, 8, 3, 15 );
178 P2( B, C, D, E, A, 1, 13, 7, 7 );
179 P2( A, B, C, D, E, 10, 11, 0, 12 );
180 P2( E, A, B, C, D, 6, 9, 13, 8 );
181 P2( D, E, A, B, C, 15, 7, 5, 9 );
182 P2( C, D, E, A, B, 3, 15, 10, 11 );
183 P2( B, C, D, E, A, 12, 7, 14, 7 );
184 P2( A, B, C, D, E, 0, 12, 15, 7 );
185 P2( E, A, B, C, D, 9, 15, 8, 12 );
186 P2( D, E, A, B, C, 5, 9, 12, 7 );
187 P2( C, D, E, A, B, 2, 11, 4, 6 );
188 P2( B, C, D, E, A, 14, 7, 9, 15 );
189 P2( A, B, C, D, E, 11, 13, 1, 13 );
190 P2( E, A, B, C, D, 8, 12, 2, 11 );
191#undef F
192#undef K
193#undef Fp
194#undef Kp
195
196#define F F3
197#define K 0x6ED9EBA1
198#define Fp F3
199#define Kp 0x6D703EF3
200 P2( D, E, A, B, C, 3, 11, 15, 9 );
201 P2( C, D, E, A, B, 10, 13, 5, 7 );
202 P2( B, C, D, E, A, 14, 6, 1, 15 );
203 P2( A, B, C, D, E, 4, 7, 3, 11 );
204 P2( E, A, B, C, D, 9, 14, 7, 8 );
205 P2( D, E, A, B, C, 15, 9, 14, 6 );
206 P2( C, D, E, A, B, 8, 13, 6, 6 );
207 P2( B, C, D, E, A, 1, 15, 9, 14 );
208 P2( A, B, C, D, E, 2, 14, 11, 12 );
209 P2( E, A, B, C, D, 7, 8, 8, 13 );
210 P2( D, E, A, B, C, 0, 13, 12, 5 );
211 P2( C, D, E, A, B, 6, 6, 2, 14 );
212 P2( B, C, D, E, A, 13, 5, 10, 13 );
213 P2( A, B, C, D, E, 11, 12, 0, 13 );
214 P2( E, A, B, C, D, 5, 7, 4, 7 );
215 P2( D, E, A, B, C, 12, 5, 13, 5 );
216#undef F
217#undef K
218#undef Fp
219#undef Kp
220
221#define F F4
222#define K 0x8F1BBCDC
223#define Fp F2
224#define Kp 0x7A6D76E9
225 P2( C, D, E, A, B, 1, 11, 8, 15 );
226 P2( B, C, D, E, A, 9, 12, 6, 5 );
227 P2( A, B, C, D, E, 11, 14, 4, 8 );
228 P2( E, A, B, C, D, 10, 15, 1, 11 );
229 P2( D, E, A, B, C, 0, 14, 3, 14 );
230 P2( C, D, E, A, B, 8, 15, 11, 14 );
231 P2( B, C, D, E, A, 12, 9, 15, 6 );
232 P2( A, B, C, D, E, 4, 8, 0, 14 );
233 P2( E, A, B, C, D, 13, 9, 5, 6 );
234 P2( D, E, A, B, C, 3, 14, 12, 9 );
235 P2( C, D, E, A, B, 7, 5, 2, 12 );
236 P2( B, C, D, E, A, 15, 6, 13, 9 );
237 P2( A, B, C, D, E, 14, 8, 9, 12 );
238 P2( E, A, B, C, D, 5, 6, 7, 5 );
239 P2( D, E, A, B, C, 6, 5, 10, 15 );
240 P2( C, D, E, A, B, 2, 12, 14, 8 );
241#undef F
242#undef K
243#undef Fp
244#undef Kp
245
246#define F F5
247#define K 0xA953FD4E
248#define Fp F1
249#define Kp 0x00000000
250 P2( B, C, D, E, A, 4, 9, 12, 8 );
251 P2( A, B, C, D, E, 0, 15, 15, 5 );
252 P2( E, A, B, C, D, 5, 5, 10, 12 );
253 P2( D, E, A, B, C, 9, 11, 4, 9 );
254 P2( C, D, E, A, B, 7, 6, 1, 12 );
255 P2( B, C, D, E, A, 12, 8, 5, 5 );
256 P2( A, B, C, D, E, 2, 13, 8, 14 );
257 P2( E, A, B, C, D, 10, 12, 7, 6 );
258 P2( D, E, A, B, C, 14, 5, 6, 8 );
259 P2( C, D, E, A, B, 1, 12, 2, 13 );
260 P2( B, C, D, E, A, 3, 13, 13, 6 );
261 P2( A, B, C, D, E, 8, 14, 14, 5 );
262 P2( E, A, B, C, D, 11, 11, 0, 15 );
263 P2( D, E, A, B, C, 6, 8, 3, 13 );
264 P2( C, D, E, A, B, 15, 5, 9, 11 );
265 P2( B, C, D, E, A, 13, 6, 11, 11 );
266#undef F
267#undef K
268#undef Fp
269#undef Kp
270
271 C = ctx->state[1] + C + Dp;
272 ctx->state[1] = ctx->state[2] + D + Ep;
273 ctx->state[2] = ctx->state[3] + E + Ap;
274 ctx->state[3] = ctx->state[4] + A + Bp;
275 ctx->state[4] = ctx->state[0] + B + Cp;
276 ctx->state[0] = C;
277}
278
279/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100280 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100281 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100282void ripemd160_update( ripemd160_context *ctx,
283 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100284{
285 size_t fill;
286 uint32_t left;
287
Brian White12895d12014-04-11 11:29:42 -0400288 if( ilen == 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100289 return;
290
291 left = ctx->total[0] & 0x3F;
292 fill = 64 - left;
293
294 ctx->total[0] += (uint32_t) ilen;
295 ctx->total[0] &= 0xFFFFFFFF;
296
297 if( ctx->total[0] < (uint32_t) ilen )
298 ctx->total[1]++;
299
300 if( left && ilen >= fill )
301 {
302 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker61b699e2014-01-22 13:35:29 +0100303 ripemd160_process( ctx, ctx->buffer );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100304 input += fill;
305 ilen -= fill;
306 left = 0;
307 }
308
309 while( ilen >= 64 )
310 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100311 ripemd160_process( ctx, input );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100312 input += 64;
313 ilen -= 64;
314 }
315
316 if( ilen > 0 )
317 {
318 memcpy( (void *) (ctx->buffer + left), input, ilen );
319 }
320}
321
Paul Bakker61b699e2014-01-22 13:35:29 +0100322static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100323{
324 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
325 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
328};
329
330/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100331 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100332 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100333void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100334{
335 uint32_t last, padn;
336 uint32_t high, low;
337 unsigned char msglen[8];
338
339 high = ( ctx->total[0] >> 29 )
340 | ( ctx->total[1] << 3 );
341 low = ( ctx->total[0] << 3 );
342
343 PUT_UINT32_LE( low, msglen, 0 );
344 PUT_UINT32_LE( high, msglen, 4 );
345
346 last = ctx->total[0] & 0x3F;
347 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
348
Paul Bakker61b699e2014-01-22 13:35:29 +0100349 ripemd160_update( ctx, ripemd160_padding, padn );
350 ripemd160_update( ctx, msglen, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100351
352 PUT_UINT32_LE( ctx->state[0], output, 0 );
353 PUT_UINT32_LE( ctx->state[1], output, 4 );
354 PUT_UINT32_LE( ctx->state[2], output, 8 );
355 PUT_UINT32_LE( ctx->state[3], output, 12 );
356 PUT_UINT32_LE( ctx->state[4], output, 16 );
357}
358
359/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100360 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100362void ripemd160( const unsigned char *input, size_t ilen,
363 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364{
Paul Bakker61b699e2014-01-22 13:35:29 +0100365 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100366
Paul Bakker61b699e2014-01-22 13:35:29 +0100367 ripemd160_starts( &ctx );
368 ripemd160_update( &ctx, input, ilen );
369 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100370
Paul Bakker34617722014-06-13 17:20:13 +0200371 polarssl_zeroize( &ctx, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372}
373
374#if defined(POLARSSL_FS_IO)
375/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100376 * output = RIPEMD-160( file contents )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100377 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100378int ripemd160_file( const char *path, unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100379{
380 FILE *f;
381 size_t n;
Paul Bakker61b699e2014-01-22 13:35:29 +0100382 ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100383 unsigned char buf[1024];
384
385 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker61b699e2014-01-22 13:35:29 +0100386 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100387
Paul Bakker61b699e2014-01-22 13:35:29 +0100388 ripemd160_starts( &ctx );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100389
390 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker61b699e2014-01-22 13:35:29 +0100391 ripemd160_update( &ctx, buf, n );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100392
Paul Bakker61b699e2014-01-22 13:35:29 +0100393 ripemd160_finish( &ctx, output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100394
Paul Bakker34617722014-06-13 17:20:13 +0200395 polarssl_zeroize( &ctx, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100396
397 if( ferror( f ) != 0 )
398 {
399 fclose( f );
Paul Bakker61b699e2014-01-22 13:35:29 +0100400 return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100401 }
402
403 fclose( f );
404 return( 0 );
405}
406#endif /* POLARSSL_FS_IO */
407
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100408/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100409 * RIPEMD-160 HMAC context setup
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100410 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100411void ripemd160_hmac_starts( ripemd160_context *ctx,
412 const unsigned char *key, size_t keylen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100413{
414 size_t i;
415 unsigned char sum[20];
416
417 if( keylen > 64 )
418 {
Paul Bakker61b699e2014-01-22 13:35:29 +0100419 ripemd160( key, keylen, sum );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100420 keylen = 20;
421 key = sum;
422 }
423
424 memset( ctx->ipad, 0x36, 64 );
425 memset( ctx->opad, 0x5C, 64 );
426
427 for( i = 0; i < keylen; i++ )
428 {
429 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
430 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
431 }
432
Paul Bakker61b699e2014-01-22 13:35:29 +0100433 ripemd160_starts( ctx );
434 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100435
Paul Bakker34617722014-06-13 17:20:13 +0200436 polarssl_zeroize( sum, sizeof( sum ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100437}
438
439/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100440 * RIPEMD-160 HMAC process buffer
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100441 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100442void ripemd160_hmac_update( ripemd160_context *ctx,
443 const unsigned char *input, size_t ilen )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100444{
Paul Bakker61b699e2014-01-22 13:35:29 +0100445 ripemd160_update( ctx, input, ilen );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100446}
447
448/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100449 * RIPEMD-160 HMAC final digest
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100450 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100451void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100452{
453 unsigned char tmpbuf[20];
454
Paul Bakker61b699e2014-01-22 13:35:29 +0100455 ripemd160_finish( ctx, tmpbuf );
456 ripemd160_starts( ctx );
457 ripemd160_update( ctx, ctx->opad, 64 );
458 ripemd160_update( ctx, tmpbuf, 20 );
459 ripemd160_finish( ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100460
Paul Bakker34617722014-06-13 17:20:13 +0200461 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100462}
463
464/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100465 * RIPEMD-160 HMAC context reset
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100466 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100467void ripemd160_hmac_reset( ripemd160_context *ctx )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100468{
Paul Bakker61b699e2014-01-22 13:35:29 +0100469 ripemd160_starts( ctx );
470 ripemd160_update( ctx, ctx->ipad, 64 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100471}
472
473/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100474 * output = HMAC-RIPEMD-160( hmac key, input buffer )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100475 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100476void ripemd160_hmac( const unsigned char *key, size_t keylen,
477 const unsigned char *input, size_t ilen,
478 unsigned char output[20] )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100479{
Paul Bakker61b699e2014-01-22 13:35:29 +0100480 ripemd160_context ctx;
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100481
Paul Bakker61b699e2014-01-22 13:35:29 +0100482 ripemd160_hmac_starts( &ctx, key, keylen );
483 ripemd160_hmac_update( &ctx, input, ilen );
484 ripemd160_hmac_finish( &ctx, output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100485
Paul Bakker34617722014-06-13 17:20:13 +0200486 polarssl_zeroize( &ctx, sizeof( ripemd160_context ) );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100487}
488
489
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100490#if defined(POLARSSL_SELF_TEST)
491/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100492 * Test vectors from the RIPEMD-160 paper and
493 * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100494 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100495#define TESTS 8
496#define KEYS 2
Paul Bakker61b699e2014-01-22 13:35:29 +0100497static const char *ripemd160_test_input[TESTS] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100498{
499 "",
500 "a",
501 "abc",
502 "message digest",
503 "abcdefghijklmnopqrstuvwxyz",
504 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
505 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
506 "1234567890123456789012345678901234567890"
507 "1234567890123456789012345678901234567890",
508};
509
Paul Bakker61b699e2014-01-22 13:35:29 +0100510static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100511{
512 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
513 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
514 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
515 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
516 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
517 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
518 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
519 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
520 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
521 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
522 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
523 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
524 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
525 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
526 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
527 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
528};
529
Paul Bakker61b699e2014-01-22 13:35:29 +0100530static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100531{
532 {
533 { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b,
534 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 },
535 { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39,
536 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc },
537 { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7,
538 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 },
539 { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60,
540 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 },
541 { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9,
542 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb },
543 { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45,
544 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 },
545 { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b,
546 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 },
547 { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06,
548 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c },
549 },
550 {
551 { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa,
552 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 },
553 { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f,
554 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd },
555 { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c,
556 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 },
557 { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c,
558 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 },
559 { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed,
560 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 },
561 { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6,
562 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a },
563 { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f,
564 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 },
565 { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe,
566 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 },
567 },
568};
569
Paul Bakker61b699e2014-01-22 13:35:29 +0100570static const unsigned char ripemd160_test_key[KEYS][20] =
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100571{
572 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
573 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 },
574 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
575 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 },
576};
577
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100578/*
579 * Checkup routine
580 */
Paul Bakker61b699e2014-01-22 13:35:29 +0100581int ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100582{
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100583 int i, j;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100584 unsigned char output[20];
585
586 memset( output, 0, sizeof output );
587
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100588 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100589 {
590 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100591 polarssl_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100592
Paul Bakker61b699e2014-01-22 13:35:29 +0100593 ripemd160( (const unsigned char *) ripemd160_test_input[i],
594 strlen( ripemd160_test_input[i] ),
595 output );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100596
Paul Bakker61b699e2014-01-22 13:35:29 +0100597 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100598 {
599 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100600 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100601
602 return( 1 );
603 }
604
605 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100606 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100607
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100608 for( j = 0; j < KEYS; j++ )
609 {
610 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100611 polarssl_printf( " HMAC-RIPEMD-160 test #%d, key #%d: ",
612 i + 1, j + 1 );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100613
Paul Bakker61b699e2014-01-22 13:35:29 +0100614 ripemd160_hmac( ripemd160_test_key[j], 20,
615 (const unsigned char *) ripemd160_test_input[i],
616 strlen( ripemd160_test_input[i] ),
617 output );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100618
Paul Bakker61b699e2014-01-22 13:35:29 +0100619 if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 )
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100620 {
621 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100622 polarssl_printf( "failed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100623
624 return( 1 );
625 }
626
627 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100628 polarssl_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100629 }
630
631 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100632 polarssl_printf( "\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100633 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100634
635 return( 0 );
636}
637
Paul Bakker9af723c2014-05-01 13:03:14 +0200638#endif /* POLARSSL_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100639
Paul Bakker9af723c2014-05-01 13:03:14 +0200640#endif /* POLARSSL_RIPEMD160_C */