blob: 2ff864f939e50fdbb745230284ab2f7d169a432a [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
Gilles Peskinedb09ef62020-06-03 01:43:33 +020028#include "common.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010031
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/ripemd160.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050033#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000034#include "mbedtls/error.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010035
Rich Evans00ab4702015-02-06 13:43:58 +000036#include <string.h>
37
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_SELF_TEST)
39#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010041#else
Rich Evans00ab4702015-02-06 13:43:58 +000042#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#define mbedtls_printf printf
44#endif /* MBEDTLS_PLATFORM_C */
45#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Gilles Peskine342d9282018-01-23 18:21:21 +010047#if !defined(MBEDTLS_RIPEMD160_ALT)
48
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020073{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020075}
76
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020078{
79 if( ctx == NULL )
80 return;
81
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050082 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020083}
84
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020085void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
86 const mbedtls_ripemd160_context *src )
87{
88 *dst = *src;
89}
90
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010091/*
Paul Bakker61b699e2014-01-22 13:35:29 +010092 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010093 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010094int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010095{
96 ctx->total[0] = 0;
97 ctx->total[1] = 0;
98
99 ctx->state[0] = 0x67452301;
100 ctx->state[1] = 0xEFCDAB89;
101 ctx->state[2] = 0x98BADCFE;
102 ctx->state[3] = 0x10325476;
103 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100104
105 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100106}
107
Jaeden Amero041039f2018-02-19 15:28:08 +0000108#if !defined(MBEDTLS_DEPRECATED_REMOVED)
109void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
110{
111 mbedtls_ripemd160_starts_ret( ctx );
112}
113#endif
114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100116/*
117 * Process one block
118 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100119int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
120 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100121{
122 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
123
124 GET_UINT32_LE( X[ 0], data, 0 );
125 GET_UINT32_LE( X[ 1], data, 4 );
126 GET_UINT32_LE( X[ 2], data, 8 );
127 GET_UINT32_LE( X[ 3], data, 12 );
128 GET_UINT32_LE( X[ 4], data, 16 );
129 GET_UINT32_LE( X[ 5], data, 20 );
130 GET_UINT32_LE( X[ 6], data, 24 );
131 GET_UINT32_LE( X[ 7], data, 28 );
132 GET_UINT32_LE( X[ 8], data, 32 );
133 GET_UINT32_LE( X[ 9], data, 36 );
134 GET_UINT32_LE( X[10], data, 40 );
135 GET_UINT32_LE( X[11], data, 44 );
136 GET_UINT32_LE( X[12], data, 48 );
137 GET_UINT32_LE( X[13], data, 52 );
138 GET_UINT32_LE( X[14], data, 56 );
139 GET_UINT32_LE( X[15], data, 60 );
140
141 A = Ap = ctx->state[0];
142 B = Bp = ctx->state[1];
143 C = Cp = ctx->state[2];
144 D = Dp = ctx->state[3];
145 E = Ep = ctx->state[4];
146
Hanno Becker1eeca412018-10-15 12:01:35 +0100147#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
148#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
149#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
150#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
151#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100152
Hanno Becker1eeca412018-10-15 12:01:35 +0100153#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100154
Hanno Becker1eeca412018-10-15 12:01:35 +0100155#define P( a, b, c, d, e, r, s, f, k ) \
156 do \
157 { \
158 (a) += f( (b), (c), (d) ) + X[r] + (k); \
159 (a) = S( (a), (s) ) + (e); \
160 (c) = S( (c), 10 ); \
161 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100162
Hanno Becker1eeca412018-10-15 12:01:35 +0100163#define P2( a, b, c, d, e, r, s, rp, sp ) \
164 do \
165 { \
166 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
167 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
168 (rp), (sp), Fp, Kp ); \
169 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100170
171#define F F1
172#define K 0x00000000
173#define Fp F5
174#define Kp 0x50A28BE6
175 P2( A, B, C, D, E, 0, 11, 5, 8 );
176 P2( E, A, B, C, D, 1, 14, 14, 9 );
177 P2( D, E, A, B, C, 2, 15, 7, 9 );
178 P2( C, D, E, A, B, 3, 12, 0, 11 );
179 P2( B, C, D, E, A, 4, 5, 9, 13 );
180 P2( A, B, C, D, E, 5, 8, 2, 15 );
181 P2( E, A, B, C, D, 6, 7, 11, 15 );
182 P2( D, E, A, B, C, 7, 9, 4, 5 );
183 P2( C, D, E, A, B, 8, 11, 13, 7 );
184 P2( B, C, D, E, A, 9, 13, 6, 7 );
185 P2( A, B, C, D, E, 10, 14, 15, 8 );
186 P2( E, A, B, C, D, 11, 15, 8, 11 );
187 P2( D, E, A, B, C, 12, 6, 1, 14 );
188 P2( C, D, E, A, B, 13, 7, 10, 14 );
189 P2( B, C, D, E, A, 14, 9, 3, 12 );
190 P2( A, B, C, D, E, 15, 8, 12, 6 );
191#undef F
192#undef K
193#undef Fp
194#undef Kp
195
196#define F F2
197#define K 0x5A827999
198#define Fp F4
199#define Kp 0x5C4DD124
200 P2( E, A, B, C, D, 7, 7, 6, 9 );
201 P2( D, E, A, B, C, 4, 6, 11, 13 );
202 P2( C, D, E, A, B, 13, 8, 3, 15 );
203 P2( B, C, D, E, A, 1, 13, 7, 7 );
204 P2( A, B, C, D, E, 10, 11, 0, 12 );
205 P2( E, A, B, C, D, 6, 9, 13, 8 );
206 P2( D, E, A, B, C, 15, 7, 5, 9 );
207 P2( C, D, E, A, B, 3, 15, 10, 11 );
208 P2( B, C, D, E, A, 12, 7, 14, 7 );
209 P2( A, B, C, D, E, 0, 12, 15, 7 );
210 P2( E, A, B, C, D, 9, 15, 8, 12 );
211 P2( D, E, A, B, C, 5, 9, 12, 7 );
212 P2( C, D, E, A, B, 2, 11, 4, 6 );
213 P2( B, C, D, E, A, 14, 7, 9, 15 );
214 P2( A, B, C, D, E, 11, 13, 1, 13 );
215 P2( E, A, B, C, D, 8, 12, 2, 11 );
216#undef F
217#undef K
218#undef Fp
219#undef Kp
220
221#define F F3
222#define K 0x6ED9EBA1
223#define Fp F3
224#define Kp 0x6D703EF3
225 P2( D, E, A, B, C, 3, 11, 15, 9 );
226 P2( C, D, E, A, B, 10, 13, 5, 7 );
227 P2( B, C, D, E, A, 14, 6, 1, 15 );
228 P2( A, B, C, D, E, 4, 7, 3, 11 );
229 P2( E, A, B, C, D, 9, 14, 7, 8 );
230 P2( D, E, A, B, C, 15, 9, 14, 6 );
231 P2( C, D, E, A, B, 8, 13, 6, 6 );
232 P2( B, C, D, E, A, 1, 15, 9, 14 );
233 P2( A, B, C, D, E, 2, 14, 11, 12 );
234 P2( E, A, B, C, D, 7, 8, 8, 13 );
235 P2( D, E, A, B, C, 0, 13, 12, 5 );
236 P2( C, D, E, A, B, 6, 6, 2, 14 );
237 P2( B, C, D, E, A, 13, 5, 10, 13 );
238 P2( A, B, C, D, E, 11, 12, 0, 13 );
239 P2( E, A, B, C, D, 5, 7, 4, 7 );
240 P2( D, E, A, B, C, 12, 5, 13, 5 );
241#undef F
242#undef K
243#undef Fp
244#undef Kp
245
246#define F F4
247#define K 0x8F1BBCDC
248#define Fp F2
249#define Kp 0x7A6D76E9
250 P2( C, D, E, A, B, 1, 11, 8, 15 );
251 P2( B, C, D, E, A, 9, 12, 6, 5 );
252 P2( A, B, C, D, E, 11, 14, 4, 8 );
253 P2( E, A, B, C, D, 10, 15, 1, 11 );
254 P2( D, E, A, B, C, 0, 14, 3, 14 );
255 P2( C, D, E, A, B, 8, 15, 11, 14 );
256 P2( B, C, D, E, A, 12, 9, 15, 6 );
257 P2( A, B, C, D, E, 4, 8, 0, 14 );
258 P2( E, A, B, C, D, 13, 9, 5, 6 );
259 P2( D, E, A, B, C, 3, 14, 12, 9 );
260 P2( C, D, E, A, B, 7, 5, 2, 12 );
261 P2( B, C, D, E, A, 15, 6, 13, 9 );
262 P2( A, B, C, D, E, 14, 8, 9, 12 );
263 P2( E, A, B, C, D, 5, 6, 7, 5 );
264 P2( D, E, A, B, C, 6, 5, 10, 15 );
265 P2( C, D, E, A, B, 2, 12, 14, 8 );
266#undef F
267#undef K
268#undef Fp
269#undef Kp
270
271#define F F5
272#define K 0xA953FD4E
273#define Fp F1
274#define Kp 0x00000000
275 P2( B, C, D, E, A, 4, 9, 12, 8 );
276 P2( A, B, C, D, E, 0, 15, 15, 5 );
277 P2( E, A, B, C, D, 5, 5, 10, 12 );
278 P2( D, E, A, B, C, 9, 11, 4, 9 );
279 P2( C, D, E, A, B, 7, 6, 1, 12 );
280 P2( B, C, D, E, A, 12, 8, 5, 5 );
281 P2( A, B, C, D, E, 2, 13, 8, 14 );
282 P2( E, A, B, C, D, 10, 12, 7, 6 );
283 P2( D, E, A, B, C, 14, 5, 6, 8 );
284 P2( C, D, E, A, B, 1, 12, 2, 13 );
285 P2( B, C, D, E, A, 3, 13, 13, 6 );
286 P2( A, B, C, D, E, 8, 14, 14, 5 );
287 P2( E, A, B, C, D, 11, 11, 0, 15 );
288 P2( D, E, A, B, C, 6, 8, 3, 13 );
289 P2( C, D, E, A, B, 15, 5, 9, 11 );
290 P2( B, C, D, E, A, 13, 6, 11, 11 );
291#undef F
292#undef K
293#undef Fp
294#undef Kp
295
296 C = ctx->state[1] + C + Dp;
297 ctx->state[1] = ctx->state[2] + D + Ep;
298 ctx->state[2] = ctx->state[3] + E + Ap;
299 ctx->state[3] = ctx->state[4] + A + Bp;
300 ctx->state[4] = ctx->state[0] + B + Cp;
301 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100302
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200303 /* Zeroise variables to clear sensitive data from memory. */
304 mbedtls_platform_zeroize( &A, sizeof( A ) );
305 mbedtls_platform_zeroize( &B, sizeof( B ) );
306 mbedtls_platform_zeroize( &C, sizeof( C ) );
307 mbedtls_platform_zeroize( &D, sizeof( D ) );
308 mbedtls_platform_zeroize( &E, sizeof( E ) );
309 mbedtls_platform_zeroize( &Ap, sizeof( Ap ) );
310 mbedtls_platform_zeroize( &Bp, sizeof( Bp ) );
311 mbedtls_platform_zeroize( &Cp, sizeof( Cp ) );
312 mbedtls_platform_zeroize( &Dp, sizeof( Dp ) );
313 mbedtls_platform_zeroize( &Ep, sizeof( Ep ) );
314 mbedtls_platform_zeroize( &X, sizeof( X ) );
315
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100316 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100317}
Jaeden Amero041039f2018-02-19 15:28:08 +0000318
319#if !defined(MBEDTLS_DEPRECATED_REMOVED)
320void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
321 const unsigned char data[64] )
322{
323 mbedtls_internal_ripemd160_process( ctx, data );
324}
325#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100327
328/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100329 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100330 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100331int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100332 const unsigned char *input,
333 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100334{
Janos Follath24eed8d2019-11-22 13:21:35 +0000335 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100336 size_t fill;
337 uint32_t left;
338
Brian White12895d12014-04-11 11:29:42 -0400339 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100340 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100341
342 left = ctx->total[0] & 0x3F;
343 fill = 64 - left;
344
345 ctx->total[0] += (uint32_t) ilen;
346 ctx->total[0] &= 0xFFFFFFFF;
347
348 if( ctx->total[0] < (uint32_t) ilen )
349 ctx->total[1]++;
350
351 if( left && ilen >= fill )
352 {
353 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100354
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100355 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100356 return( ret );
357
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100358 input += fill;
359 ilen -= fill;
360 left = 0;
361 }
362
363 while( ilen >= 64 )
364 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100365 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100366 return( ret );
367
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100368 input += 64;
369 ilen -= 64;
370 }
371
372 if( ilen > 0 )
373 {
374 memcpy( (void *) (ctx->buffer + left), input, ilen );
375 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100376
377 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100378}
379
Jaeden Amero041039f2018-02-19 15:28:08 +0000380#if !defined(MBEDTLS_DEPRECATED_REMOVED)
381void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
382 const unsigned char *input,
383 size_t ilen )
384{
385 mbedtls_ripemd160_update_ret( ctx, input, ilen );
386}
387#endif
388
Paul Bakker61b699e2014-01-22 13:35:29 +0100389static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100390{
391 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
392 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
395};
396
397/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100398 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100399 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100400int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100401 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100402{
Janos Follath24eed8d2019-11-22 13:21:35 +0000403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100404 uint32_t last, padn;
405 uint32_t high, low;
406 unsigned char msglen[8];
407
408 high = ( ctx->total[0] >> 29 )
409 | ( ctx->total[1] << 3 );
410 low = ( ctx->total[0] << 3 );
411
412 PUT_UINT32_LE( low, msglen, 0 );
413 PUT_UINT32_LE( high, msglen, 4 );
414
415 last = ctx->total[0] & 0x3F;
416 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
417
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100418 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100419 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100420 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100421
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100422 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100423 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100424 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100425
426 PUT_UINT32_LE( ctx->state[0], output, 0 );
427 PUT_UINT32_LE( ctx->state[1], output, 4 );
428 PUT_UINT32_LE( ctx->state[2], output, 8 );
429 PUT_UINT32_LE( ctx->state[3], output, 12 );
430 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100431
432 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100433}
434
Jaeden Amero041039f2018-02-19 15:28:08 +0000435#if !defined(MBEDTLS_DEPRECATED_REMOVED)
436void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
437 unsigned char output[20] )
438{
439 mbedtls_ripemd160_finish_ret( ctx, output );
440}
441#endif
442
Gilles Peskine342d9282018-01-23 18:21:21 +0100443#endif /* ! MBEDTLS_RIPEMD160_ALT */
444
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100445/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100446 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100447 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100448int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100449 size_t ilen,
450 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100451{
Janos Follath24eed8d2019-11-22 13:21:35 +0000452 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100456
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100457 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100458 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100459
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100460 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100461 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100462
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100463 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100464 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100465
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100466exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100468
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100469 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100470}
471
Jaeden Amero041039f2018-02-19 15:28:08 +0000472#if !defined(MBEDTLS_DEPRECATED_REMOVED)
473void mbedtls_ripemd160( const unsigned char *input,
474 size_t ilen,
475 unsigned char output[20] )
476{
477 mbedtls_ripemd160_ret( input, ilen, output );
478}
479#endif
480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100482/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100483 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100486#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100487static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100488{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100489 { "" },
490 { "a" },
491 { "abc" },
492 { "message digest" },
493 { "abcdefghijklmnopqrstuvwxyz" },
494 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
495 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
496 { "12345678901234567890123456789012345678901234567890123456789012"
497 "345678901234567890" },
498};
499
500static const size_t ripemd160_test_strlen[TESTS] =
501{
502 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100503};
504
Paul Bakker61b699e2014-01-22 13:35:29 +0100505static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100506{
507 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
508 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
509 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
510 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
511 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
512 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
513 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
514 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
515 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
516 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
517 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
518 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
519 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
520 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
521 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
522 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
523};
524
525/*
526 * Checkup routine
527 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100529{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100530 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100531 unsigned char output[20];
532
533 memset( output, 0, sizeof output );
534
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100535 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100536 {
537 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100539
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100540 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100541 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100542 if( ret != 0 )
543 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100544
Paul Bakker61b699e2014-01-22 13:35:29 +0100545 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100546 {
547 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100548 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100549 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100550
551 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100553 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100554
Paul Bakker4400ecc2016-07-19 14:41:43 +0100555 if( verbose != 0 )
556 mbedtls_printf( "\n" );
557
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100558 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100559
560fail:
561 if( verbose != 0 )
562 mbedtls_printf( "failed\n" );
563
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100564 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100565}
566
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569#endif /* MBEDTLS_RIPEMD160_C */