blob: 260fee68683270ce1e1b3b8092bd3218d0f24def [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010020 */
21
22/*
23 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020024 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010025 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/ripemd160.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#define mbedtls_printf printf
46#endif /* MBEDTLS_PLATFORM_C */
47#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010049/*
50 * 32-bit integer manipulation macros (little endian)
51 */
52#ifndef GET_UINT32_LE
53#define GET_UINT32_LE(n,b,i) \
54{ \
55 (n) = ( (uint32_t) (b)[(i) ] ) \
56 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
57 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
58 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
59}
60#endif
61
62#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000063#define PUT_UINT32_LE(n,b,i) \
64{ \
65 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
66 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
67 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
68 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010069}
70#endif
71
Paul Bakker34617722014-06-13 17:20:13 +020072/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020074 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
75}
76
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020078{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020080}
81
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020083{
84 if( ctx == NULL )
85 return;
86
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087 mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020088}
89
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020090void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
91 const mbedtls_ripemd160_context *src )
92{
93 *dst = *src;
94}
95
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010096/*
Paul Bakker61b699e2014-01-22 13:35:29 +010097 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010098 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010099int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100100{
101 ctx->total[0] = 0;
102 ctx->total[1] = 0;
103
104 ctx->state[0] = 0x67452301;
105 ctx->state[1] = 0xEFCDAB89;
106 ctx->state[2] = 0x98BADCFE;
107 ctx->state[3] = 0x10325476;
108 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100109
110 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100111}
112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100114/*
115 * Process one block
116 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100117int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
118 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100119{
120 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
121
122 GET_UINT32_LE( X[ 0], data, 0 );
123 GET_UINT32_LE( X[ 1], data, 4 );
124 GET_UINT32_LE( X[ 2], data, 8 );
125 GET_UINT32_LE( X[ 3], data, 12 );
126 GET_UINT32_LE( X[ 4], data, 16 );
127 GET_UINT32_LE( X[ 5], data, 20 );
128 GET_UINT32_LE( X[ 6], data, 24 );
129 GET_UINT32_LE( X[ 7], data, 28 );
130 GET_UINT32_LE( X[ 8], data, 32 );
131 GET_UINT32_LE( X[ 9], data, 36 );
132 GET_UINT32_LE( X[10], data, 40 );
133 GET_UINT32_LE( X[11], data, 44 );
134 GET_UINT32_LE( X[12], data, 48 );
135 GET_UINT32_LE( X[13], data, 52 );
136 GET_UINT32_LE( X[14], data, 56 );
137 GET_UINT32_LE( X[15], data, 60 );
138
139 A = Ap = ctx->state[0];
140 B = Bp = ctx->state[1];
141 C = Cp = ctx->state[2];
142 D = Dp = ctx->state[3];
143 E = Ep = ctx->state[4];
144
145#define F1( x, y, z ) ( x ^ y ^ z )
146#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
147#define F3( x, y, z ) ( ( x | ~y ) ^ z )
148#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
149#define F5( x, y, z ) ( x ^ ( y | ~z ) )
150
151#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
152
153#define P( a, b, c, d, e, r, s, f, k ) \
154 a += f( b, c, d ) + X[r] + k; \
155 a = S( a, s ) + e; \
156 c = S( c, 10 );
157
158#define P2( a, b, c, d, e, r, s, rp, sp ) \
159 P( a, b, c, d, e, r, s, F, K ); \
160 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
161
162#define F F1
163#define K 0x00000000
164#define Fp F5
165#define Kp 0x50A28BE6
166 P2( A, B, C, D, E, 0, 11, 5, 8 );
167 P2( E, A, B, C, D, 1, 14, 14, 9 );
168 P2( D, E, A, B, C, 2, 15, 7, 9 );
169 P2( C, D, E, A, B, 3, 12, 0, 11 );
170 P2( B, C, D, E, A, 4, 5, 9, 13 );
171 P2( A, B, C, D, E, 5, 8, 2, 15 );
172 P2( E, A, B, C, D, 6, 7, 11, 15 );
173 P2( D, E, A, B, C, 7, 9, 4, 5 );
174 P2( C, D, E, A, B, 8, 11, 13, 7 );
175 P2( B, C, D, E, A, 9, 13, 6, 7 );
176 P2( A, B, C, D, E, 10, 14, 15, 8 );
177 P2( E, A, B, C, D, 11, 15, 8, 11 );
178 P2( D, E, A, B, C, 12, 6, 1, 14 );
179 P2( C, D, E, A, B, 13, 7, 10, 14 );
180 P2( B, C, D, E, A, 14, 9, 3, 12 );
181 P2( A, B, C, D, E, 15, 8, 12, 6 );
182#undef F
183#undef K
184#undef Fp
185#undef Kp
186
187#define F F2
188#define K 0x5A827999
189#define Fp F4
190#define Kp 0x5C4DD124
191 P2( E, A, B, C, D, 7, 7, 6, 9 );
192 P2( D, E, A, B, C, 4, 6, 11, 13 );
193 P2( C, D, E, A, B, 13, 8, 3, 15 );
194 P2( B, C, D, E, A, 1, 13, 7, 7 );
195 P2( A, B, C, D, E, 10, 11, 0, 12 );
196 P2( E, A, B, C, D, 6, 9, 13, 8 );
197 P2( D, E, A, B, C, 15, 7, 5, 9 );
198 P2( C, D, E, A, B, 3, 15, 10, 11 );
199 P2( B, C, D, E, A, 12, 7, 14, 7 );
200 P2( A, B, C, D, E, 0, 12, 15, 7 );
201 P2( E, A, B, C, D, 9, 15, 8, 12 );
202 P2( D, E, A, B, C, 5, 9, 12, 7 );
203 P2( C, D, E, A, B, 2, 11, 4, 6 );
204 P2( B, C, D, E, A, 14, 7, 9, 15 );
205 P2( A, B, C, D, E, 11, 13, 1, 13 );
206 P2( E, A, B, C, D, 8, 12, 2, 11 );
207#undef F
208#undef K
209#undef Fp
210#undef Kp
211
212#define F F3
213#define K 0x6ED9EBA1
214#define Fp F3
215#define Kp 0x6D703EF3
216 P2( D, E, A, B, C, 3, 11, 15, 9 );
217 P2( C, D, E, A, B, 10, 13, 5, 7 );
218 P2( B, C, D, E, A, 14, 6, 1, 15 );
219 P2( A, B, C, D, E, 4, 7, 3, 11 );
220 P2( E, A, B, C, D, 9, 14, 7, 8 );
221 P2( D, E, A, B, C, 15, 9, 14, 6 );
222 P2( C, D, E, A, B, 8, 13, 6, 6 );
223 P2( B, C, D, E, A, 1, 15, 9, 14 );
224 P2( A, B, C, D, E, 2, 14, 11, 12 );
225 P2( E, A, B, C, D, 7, 8, 8, 13 );
226 P2( D, E, A, B, C, 0, 13, 12, 5 );
227 P2( C, D, E, A, B, 6, 6, 2, 14 );
228 P2( B, C, D, E, A, 13, 5, 10, 13 );
229 P2( A, B, C, D, E, 11, 12, 0, 13 );
230 P2( E, A, B, C, D, 5, 7, 4, 7 );
231 P2( D, E, A, B, C, 12, 5, 13, 5 );
232#undef F
233#undef K
234#undef Fp
235#undef Kp
236
237#define F F4
238#define K 0x8F1BBCDC
239#define Fp F2
240#define Kp 0x7A6D76E9
241 P2( C, D, E, A, B, 1, 11, 8, 15 );
242 P2( B, C, D, E, A, 9, 12, 6, 5 );
243 P2( A, B, C, D, E, 11, 14, 4, 8 );
244 P2( E, A, B, C, D, 10, 15, 1, 11 );
245 P2( D, E, A, B, C, 0, 14, 3, 14 );
246 P2( C, D, E, A, B, 8, 15, 11, 14 );
247 P2( B, C, D, E, A, 12, 9, 15, 6 );
248 P2( A, B, C, D, E, 4, 8, 0, 14 );
249 P2( E, A, B, C, D, 13, 9, 5, 6 );
250 P2( D, E, A, B, C, 3, 14, 12, 9 );
251 P2( C, D, E, A, B, 7, 5, 2, 12 );
252 P2( B, C, D, E, A, 15, 6, 13, 9 );
253 P2( A, B, C, D, E, 14, 8, 9, 12 );
254 P2( E, A, B, C, D, 5, 6, 7, 5 );
255 P2( D, E, A, B, C, 6, 5, 10, 15 );
256 P2( C, D, E, A, B, 2, 12, 14, 8 );
257#undef F
258#undef K
259#undef Fp
260#undef Kp
261
262#define F F5
263#define K 0xA953FD4E
264#define Fp F1
265#define Kp 0x00000000
266 P2( B, C, D, E, A, 4, 9, 12, 8 );
267 P2( A, B, C, D, E, 0, 15, 15, 5 );
268 P2( E, A, B, C, D, 5, 5, 10, 12 );
269 P2( D, E, A, B, C, 9, 11, 4, 9 );
270 P2( C, D, E, A, B, 7, 6, 1, 12 );
271 P2( B, C, D, E, A, 12, 8, 5, 5 );
272 P2( A, B, C, D, E, 2, 13, 8, 14 );
273 P2( E, A, B, C, D, 10, 12, 7, 6 );
274 P2( D, E, A, B, C, 14, 5, 6, 8 );
275 P2( C, D, E, A, B, 1, 12, 2, 13 );
276 P2( B, C, D, E, A, 3, 13, 13, 6 );
277 P2( A, B, C, D, E, 8, 14, 14, 5 );
278 P2( E, A, B, C, D, 11, 11, 0, 15 );
279 P2( D, E, A, B, C, 6, 8, 3, 13 );
280 P2( C, D, E, A, B, 15, 5, 9, 11 );
281 P2( B, C, D, E, A, 13, 6, 11, 11 );
282#undef F
283#undef K
284#undef Fp
285#undef Kp
286
287 C = ctx->state[1] + C + Dp;
288 ctx->state[1] = ctx->state[2] + D + Ep;
289 ctx->state[2] = ctx->state[3] + E + Ap;
290 ctx->state[3] = ctx->state[4] + A + Bp;
291 ctx->state[4] = ctx->state[0] + B + Cp;
292 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100293
294 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100295}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200296#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297
298/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100299 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100300 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100301int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100302 const unsigned char *input,
303 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100304{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100305 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100306 size_t fill;
307 uint32_t left;
308
Brian White12895d12014-04-11 11:29:42 -0400309 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100310 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100311
312 left = ctx->total[0] & 0x3F;
313 fill = 64 - left;
314
315 ctx->total[0] += (uint32_t) ilen;
316 ctx->total[0] &= 0xFFFFFFFF;
317
318 if( ctx->total[0] < (uint32_t) ilen )
319 ctx->total[1]++;
320
321 if( left && ilen >= fill )
322 {
323 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100324
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100325 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100326 return( ret );
327
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100328 input += fill;
329 ilen -= fill;
330 left = 0;
331 }
332
333 while( ilen >= 64 )
334 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100335 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100336 return( ret );
337
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100338 input += 64;
339 ilen -= 64;
340 }
341
342 if( ilen > 0 )
343 {
344 memcpy( (void *) (ctx->buffer + left), input, ilen );
345 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100346
347 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100348}
349
Paul Bakker61b699e2014-01-22 13:35:29 +0100350static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100351{
352 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
353 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
355 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
356};
357
358/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100359 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100360 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100361int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100362 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100363{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100364 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100365 uint32_t last, padn;
366 uint32_t high, low;
367 unsigned char msglen[8];
368
369 high = ( ctx->total[0] >> 29 )
370 | ( ctx->total[1] << 3 );
371 low = ( ctx->total[0] << 3 );
372
373 PUT_UINT32_LE( low, msglen, 0 );
374 PUT_UINT32_LE( high, msglen, 4 );
375
376 last = ctx->total[0] & 0x3F;
377 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
378
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100379 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100380 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100381 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100382
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100383 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100384 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100385 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100386
387 PUT_UINT32_LE( ctx->state[0], output, 0 );
388 PUT_UINT32_LE( ctx->state[1], output, 4 );
389 PUT_UINT32_LE( ctx->state[2], output, 8 );
390 PUT_UINT32_LE( ctx->state[3], output, 12 );
391 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100392
393 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100394}
395
396/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100397 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100398 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100399int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100400 size_t ilen,
401 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100402{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100403 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100405
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100407
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100408 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100409 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100410
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100411 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100412 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100413
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100414 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100415 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100416
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100417exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100419
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100420 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100421}
422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100424/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100425 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100427 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100428#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100429static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100430{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100431 { "" },
432 { "a" },
433 { "abc" },
434 { "message digest" },
435 { "abcdefghijklmnopqrstuvwxyz" },
436 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
437 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
438 { "12345678901234567890123456789012345678901234567890123456789012"
439 "345678901234567890" },
440};
441
442static const size_t ripemd160_test_strlen[TESTS] =
443{
444 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100445};
446
Paul Bakker61b699e2014-01-22 13:35:29 +0100447static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100448{
449 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
450 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
451 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
452 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
453 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
454 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
455 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
456 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
457 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
458 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
459 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
460 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
461 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
462 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
463 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
464 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
465};
466
467/*
468 * Checkup routine
469 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100471{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100472 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100473 unsigned char output[20];
474
475 memset( output, 0, sizeof output );
476
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100477 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100478 {
479 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100481
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100482 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100483 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100484 if( ret != 0 )
485 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100486
Paul Bakker61b699e2014-01-22 13:35:29 +0100487 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100488 {
489 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100490 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100491 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100492
493 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100495 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100496
Paul Bakker4400ecc2016-07-19 14:41:43 +0100497 if( verbose != 0 )
498 mbedtls_printf( "\n" );
499
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100500 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100501
502fail:
503 if( verbose != 0 )
504 mbedtls_printf( "failed\n" );
505
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100506 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100507}
508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511#endif /* MBEDTLS_RIPEMD160_C */