blob: 830f61b3cd53f2ef87cfa46fd2e011f6a6cbf0b0 [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 */
19
20/*
21 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010023 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/ripemd160.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000032#include "mbedtls/error.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_SELF_TEST)
37#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010039#else
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_printf printf
42#endif /* MBEDTLS_PLATFORM_C */
43#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Gilles Peskine342d9282018-01-23 18:21:21 +010045#if !defined(MBEDTLS_RIPEMD160_ALT)
46
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010047/*
48 * 32-bit integer manipulation macros (little endian)
49 */
50#ifndef GET_UINT32_LE
51#define GET_UINT32_LE(n,b,i) \
52{ \
53 (n) = ( (uint32_t) (b)[(i) ] ) \
54 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
55 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
56 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
57}
58#endif
59
60#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000061#define PUT_UINT32_LE(n,b,i) \
62{ \
63 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
64 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
65 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
66 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010067}
68#endif
69
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020071{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020073}
74
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020076{
77 if( ctx == NULL )
78 return;
79
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050080 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020081}
82
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020083void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
84 const mbedtls_ripemd160_context *src )
85{
86 *dst = *src;
87}
88
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010089/*
Paul Bakker61b699e2014-01-22 13:35:29 +010090 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010091 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010092int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010093{
94 ctx->total[0] = 0;
95 ctx->total[1] = 0;
96
97 ctx->state[0] = 0x67452301;
98 ctx->state[1] = 0xEFCDAB89;
99 ctx->state[2] = 0x98BADCFE;
100 ctx->state[3] = 0x10325476;
101 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100102
103 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100104}
105
Jaeden Amero041039f2018-02-19 15:28:08 +0000106#if !defined(MBEDTLS_DEPRECATED_REMOVED)
107void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
108{
109 mbedtls_ripemd160_starts_ret( ctx );
110}
111#endif
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
Hanno Becker1eeca412018-10-15 12:01:35 +0100145#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) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100150
Hanno Becker1eeca412018-10-15 12:01:35 +0100151#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100152
Hanno Becker1eeca412018-10-15 12:01:35 +0100153#define P( a, b, c, d, e, r, s, f, k ) \
154 do \
155 { \
156 (a) += f( (b), (c), (d) ) + X[r] + (k); \
157 (a) = S( (a), (s) ) + (e); \
158 (c) = S( (c), 10 ); \
159 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100160
Hanno Becker1eeca412018-10-15 12:01:35 +0100161#define P2( a, b, c, d, e, r, s, rp, sp ) \
162 do \
163 { \
164 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
165 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
166 (rp), (sp), Fp, Kp ); \
167 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100168
169#define F F1
170#define K 0x00000000
171#define Fp F5
172#define Kp 0x50A28BE6
173 P2( A, B, C, D, E, 0, 11, 5, 8 );
174 P2( E, A, B, C, D, 1, 14, 14, 9 );
175 P2( D, E, A, B, C, 2, 15, 7, 9 );
176 P2( C, D, E, A, B, 3, 12, 0, 11 );
177 P2( B, C, D, E, A, 4, 5, 9, 13 );
178 P2( A, B, C, D, E, 5, 8, 2, 15 );
179 P2( E, A, B, C, D, 6, 7, 11, 15 );
180 P2( D, E, A, B, C, 7, 9, 4, 5 );
181 P2( C, D, E, A, B, 8, 11, 13, 7 );
182 P2( B, C, D, E, A, 9, 13, 6, 7 );
183 P2( A, B, C, D, E, 10, 14, 15, 8 );
184 P2( E, A, B, C, D, 11, 15, 8, 11 );
185 P2( D, E, A, B, C, 12, 6, 1, 14 );
186 P2( C, D, E, A, B, 13, 7, 10, 14 );
187 P2( B, C, D, E, A, 14, 9, 3, 12 );
188 P2( A, B, C, D, E, 15, 8, 12, 6 );
189#undef F
190#undef K
191#undef Fp
192#undef Kp
193
194#define F F2
195#define K 0x5A827999
196#define Fp F4
197#define Kp 0x5C4DD124
198 P2( E, A, B, C, D, 7, 7, 6, 9 );
199 P2( D, E, A, B, C, 4, 6, 11, 13 );
200 P2( C, D, E, A, B, 13, 8, 3, 15 );
201 P2( B, C, D, E, A, 1, 13, 7, 7 );
202 P2( A, B, C, D, E, 10, 11, 0, 12 );
203 P2( E, A, B, C, D, 6, 9, 13, 8 );
204 P2( D, E, A, B, C, 15, 7, 5, 9 );
205 P2( C, D, E, A, B, 3, 15, 10, 11 );
206 P2( B, C, D, E, A, 12, 7, 14, 7 );
207 P2( A, B, C, D, E, 0, 12, 15, 7 );
208 P2( E, A, B, C, D, 9, 15, 8, 12 );
209 P2( D, E, A, B, C, 5, 9, 12, 7 );
210 P2( C, D, E, A, B, 2, 11, 4, 6 );
211 P2( B, C, D, E, A, 14, 7, 9, 15 );
212 P2( A, B, C, D, E, 11, 13, 1, 13 );
213 P2( E, A, B, C, D, 8, 12, 2, 11 );
214#undef F
215#undef K
216#undef Fp
217#undef Kp
218
219#define F F3
220#define K 0x6ED9EBA1
221#define Fp F3
222#define Kp 0x6D703EF3
223 P2( D, E, A, B, C, 3, 11, 15, 9 );
224 P2( C, D, E, A, B, 10, 13, 5, 7 );
225 P2( B, C, D, E, A, 14, 6, 1, 15 );
226 P2( A, B, C, D, E, 4, 7, 3, 11 );
227 P2( E, A, B, C, D, 9, 14, 7, 8 );
228 P2( D, E, A, B, C, 15, 9, 14, 6 );
229 P2( C, D, E, A, B, 8, 13, 6, 6 );
230 P2( B, C, D, E, A, 1, 15, 9, 14 );
231 P2( A, B, C, D, E, 2, 14, 11, 12 );
232 P2( E, A, B, C, D, 7, 8, 8, 13 );
233 P2( D, E, A, B, C, 0, 13, 12, 5 );
234 P2( C, D, E, A, B, 6, 6, 2, 14 );
235 P2( B, C, D, E, A, 13, 5, 10, 13 );
236 P2( A, B, C, D, E, 11, 12, 0, 13 );
237 P2( E, A, B, C, D, 5, 7, 4, 7 );
238 P2( D, E, A, B, C, 12, 5, 13, 5 );
239#undef F
240#undef K
241#undef Fp
242#undef Kp
243
244#define F F4
245#define K 0x8F1BBCDC
246#define Fp F2
247#define Kp 0x7A6D76E9
248 P2( C, D, E, A, B, 1, 11, 8, 15 );
249 P2( B, C, D, E, A, 9, 12, 6, 5 );
250 P2( A, B, C, D, E, 11, 14, 4, 8 );
251 P2( E, A, B, C, D, 10, 15, 1, 11 );
252 P2( D, E, A, B, C, 0, 14, 3, 14 );
253 P2( C, D, E, A, B, 8, 15, 11, 14 );
254 P2( B, C, D, E, A, 12, 9, 15, 6 );
255 P2( A, B, C, D, E, 4, 8, 0, 14 );
256 P2( E, A, B, C, D, 13, 9, 5, 6 );
257 P2( D, E, A, B, C, 3, 14, 12, 9 );
258 P2( C, D, E, A, B, 7, 5, 2, 12 );
259 P2( B, C, D, E, A, 15, 6, 13, 9 );
260 P2( A, B, C, D, E, 14, 8, 9, 12 );
261 P2( E, A, B, C, D, 5, 6, 7, 5 );
262 P2( D, E, A, B, C, 6, 5, 10, 15 );
263 P2( C, D, E, A, B, 2, 12, 14, 8 );
264#undef F
265#undef K
266#undef Fp
267#undef Kp
268
269#define F F5
270#define K 0xA953FD4E
271#define Fp F1
272#define Kp 0x00000000
273 P2( B, C, D, E, A, 4, 9, 12, 8 );
274 P2( A, B, C, D, E, 0, 15, 15, 5 );
275 P2( E, A, B, C, D, 5, 5, 10, 12 );
276 P2( D, E, A, B, C, 9, 11, 4, 9 );
277 P2( C, D, E, A, B, 7, 6, 1, 12 );
278 P2( B, C, D, E, A, 12, 8, 5, 5 );
279 P2( A, B, C, D, E, 2, 13, 8, 14 );
280 P2( E, A, B, C, D, 10, 12, 7, 6 );
281 P2( D, E, A, B, C, 14, 5, 6, 8 );
282 P2( C, D, E, A, B, 1, 12, 2, 13 );
283 P2( B, C, D, E, A, 3, 13, 13, 6 );
284 P2( A, B, C, D, E, 8, 14, 14, 5 );
285 P2( E, A, B, C, D, 11, 11, 0, 15 );
286 P2( D, E, A, B, C, 6, 8, 3, 13 );
287 P2( C, D, E, A, B, 15, 5, 9, 11 );
288 P2( B, C, D, E, A, 13, 6, 11, 11 );
289#undef F
290#undef K
291#undef Fp
292#undef Kp
293
294 C = ctx->state[1] + C + Dp;
295 ctx->state[1] = ctx->state[2] + D + Ep;
296 ctx->state[2] = ctx->state[3] + E + Ap;
297 ctx->state[3] = ctx->state[4] + A + Bp;
298 ctx->state[4] = ctx->state[0] + B + Cp;
299 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100300
301 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100302}
Jaeden Amero041039f2018-02-19 15:28:08 +0000303
304#if !defined(MBEDTLS_DEPRECATED_REMOVED)
305void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
306 const unsigned char data[64] )
307{
308 mbedtls_internal_ripemd160_process( ctx, data );
309}
310#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100312
313/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100314 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100315 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100316int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100317 const unsigned char *input,
318 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100319{
Janos Follath24eed8d2019-11-22 13:21:35 +0000320 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100321 size_t fill;
322 uint32_t left;
323
Brian White12895d12014-04-11 11:29:42 -0400324 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100325 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100326
327 left = ctx->total[0] & 0x3F;
328 fill = 64 - left;
329
330 ctx->total[0] += (uint32_t) ilen;
331 ctx->total[0] &= 0xFFFFFFFF;
332
333 if( ctx->total[0] < (uint32_t) ilen )
334 ctx->total[1]++;
335
336 if( left && ilen >= fill )
337 {
338 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100339
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100340 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100341 return( ret );
342
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100343 input += fill;
344 ilen -= fill;
345 left = 0;
346 }
347
348 while( ilen >= 64 )
349 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100350 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100351 return( ret );
352
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100353 input += 64;
354 ilen -= 64;
355 }
356
357 if( ilen > 0 )
358 {
359 memcpy( (void *) (ctx->buffer + left), input, ilen );
360 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100361
362 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100363}
364
Jaeden Amero041039f2018-02-19 15:28:08 +0000365#if !defined(MBEDTLS_DEPRECATED_REMOVED)
366void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
367 const unsigned char *input,
368 size_t ilen )
369{
370 mbedtls_ripemd160_update_ret( ctx, input, ilen );
371}
372#endif
373
Paul Bakker61b699e2014-01-22 13:35:29 +0100374static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100375{
376 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
377 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
378 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
379 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
380};
381
382/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100383 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100384 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100385int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100386 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100387{
Janos Follath24eed8d2019-11-22 13:21:35 +0000388 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100389 uint32_t last, padn;
390 uint32_t high, low;
391 unsigned char msglen[8];
392
393 high = ( ctx->total[0] >> 29 )
394 | ( ctx->total[1] << 3 );
395 low = ( ctx->total[0] << 3 );
396
397 PUT_UINT32_LE( low, msglen, 0 );
398 PUT_UINT32_LE( high, msglen, 4 );
399
400 last = ctx->total[0] & 0x3F;
401 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
402
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100403 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100404 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100405 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100406
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100407 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100408 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100409 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100410
411 PUT_UINT32_LE( ctx->state[0], output, 0 );
412 PUT_UINT32_LE( ctx->state[1], output, 4 );
413 PUT_UINT32_LE( ctx->state[2], output, 8 );
414 PUT_UINT32_LE( ctx->state[3], output, 12 );
415 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100416
417 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100418}
419
Jaeden Amero041039f2018-02-19 15:28:08 +0000420#if !defined(MBEDTLS_DEPRECATED_REMOVED)
421void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
422 unsigned char output[20] )
423{
424 mbedtls_ripemd160_finish_ret( ctx, output );
425}
426#endif
427
Gilles Peskine342d9282018-01-23 18:21:21 +0100428#endif /* ! MBEDTLS_RIPEMD160_ALT */
429
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100430/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100431 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100432 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100433int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100434 size_t ilen,
435 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100436{
Janos Follath24eed8d2019-11-22 13:21:35 +0000437 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100441
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100442 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100443 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100444
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100445 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100446 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100447
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100448 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100449 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100450
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100451exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100453
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100454 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100455}
456
Jaeden Amero041039f2018-02-19 15:28:08 +0000457#if !defined(MBEDTLS_DEPRECATED_REMOVED)
458void mbedtls_ripemd160( const unsigned char *input,
459 size_t ilen,
460 unsigned char output[20] )
461{
462 mbedtls_ripemd160_ret( input, ilen, output );
463}
464#endif
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100467/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100468 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100470 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100471#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100472static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100473{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100474 { "" },
475 { "a" },
476 { "abc" },
477 { "message digest" },
478 { "abcdefghijklmnopqrstuvwxyz" },
479 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
480 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
481 { "12345678901234567890123456789012345678901234567890123456789012"
482 "345678901234567890" },
483};
484
485static const size_t ripemd160_test_strlen[TESTS] =
486{
487 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100488};
489
Paul Bakker61b699e2014-01-22 13:35:29 +0100490static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100491{
492 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
493 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
494 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
495 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
496 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
497 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
498 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
499 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
500 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
501 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
502 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
503 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
504 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
505 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
506 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
507 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
508};
509
510/*
511 * Checkup routine
512 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100514{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100515 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100516 unsigned char output[20];
517
518 memset( output, 0, sizeof output );
519
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100520 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100521 {
522 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100524
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100525 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100526 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100527 if( ret != 0 )
528 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100529
Paul Bakker61b699e2014-01-22 13:35:29 +0100530 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100531 {
532 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100533 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100534 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100535
536 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100538 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100539
Paul Bakker4400ecc2016-07-19 14:41:43 +0100540 if( verbose != 0 )
541 mbedtls_printf( "\n" );
542
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100543 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100544
545fail:
546 if( verbose != 0 )
547 mbedtls_printf( "failed\n" );
548
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100549 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100550}
551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554#endif /* MBEDTLS_RIPEMD160_C */