blob: b991b56897ea5c96666cca2dd382782e8d0a58b0 [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010045 */
46
47/*
48 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010050 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
51 */
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010060
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/ripemd160.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050062#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010063
Rich Evans00ab4702015-02-06 13:43:58 +000064#include <string.h>
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_SELF_TEST)
67#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000068#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010069#else
Rich Evans00ab4702015-02-06 13:43:58 +000070#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071#define mbedtls_printf printf
72#endif /* MBEDTLS_PLATFORM_C */
73#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010074
Gilles Peskine342d9282018-01-23 18:21:21 +010075#if !defined(MBEDTLS_RIPEMD160_ALT)
76
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010077/*
78 * 32-bit integer manipulation macros (little endian)
79 */
80#ifndef GET_UINT32_LE
81#define GET_UINT32_LE(n,b,i) \
82{ \
83 (n) = ( (uint32_t) (b)[(i) ] ) \
84 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
85 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
86 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
87}
88#endif
89
90#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000091#define PUT_UINT32_LE(n,b,i) \
92{ \
93 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
94 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
95 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
96 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010097}
98#endif
99
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200101{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200103}
104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200106{
107 if( ctx == NULL )
108 return;
109
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500110 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200111}
112
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200113void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
114 const mbedtls_ripemd160_context *src )
115{
116 *dst = *src;
117}
118
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100119/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100120 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100121 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100122int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100123{
124 ctx->total[0] = 0;
125 ctx->total[1] = 0;
126
127 ctx->state[0] = 0x67452301;
128 ctx->state[1] = 0xEFCDAB89;
129 ctx->state[2] = 0x98BADCFE;
130 ctx->state[3] = 0x10325476;
131 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100132
133 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100134}
135
Jaeden Amero041039f2018-02-19 15:28:08 +0000136#if !defined(MBEDTLS_DEPRECATED_REMOVED)
137void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
138{
139 mbedtls_ripemd160_starts_ret( ctx );
140}
141#endif
142
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100144/*
145 * Process one block
146 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100147int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
148 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100149{
150 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
151
152 GET_UINT32_LE( X[ 0], data, 0 );
153 GET_UINT32_LE( X[ 1], data, 4 );
154 GET_UINT32_LE( X[ 2], data, 8 );
155 GET_UINT32_LE( X[ 3], data, 12 );
156 GET_UINT32_LE( X[ 4], data, 16 );
157 GET_UINT32_LE( X[ 5], data, 20 );
158 GET_UINT32_LE( X[ 6], data, 24 );
159 GET_UINT32_LE( X[ 7], data, 28 );
160 GET_UINT32_LE( X[ 8], data, 32 );
161 GET_UINT32_LE( X[ 9], data, 36 );
162 GET_UINT32_LE( X[10], data, 40 );
163 GET_UINT32_LE( X[11], data, 44 );
164 GET_UINT32_LE( X[12], data, 48 );
165 GET_UINT32_LE( X[13], data, 52 );
166 GET_UINT32_LE( X[14], data, 56 );
167 GET_UINT32_LE( X[15], data, 60 );
168
169 A = Ap = ctx->state[0];
170 B = Bp = ctx->state[1];
171 C = Cp = ctx->state[2];
172 D = Dp = ctx->state[3];
173 E = Ep = ctx->state[4];
174
Hanno Beckerd6028a12018-10-15 12:01:35 +0100175#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
176#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
177#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
178#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
179#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100180
Hanno Beckerd6028a12018-10-15 12:01:35 +0100181#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100182
Hanno Beckerd6028a12018-10-15 12:01:35 +0100183#define P( a, b, c, d, e, r, s, f, k ) \
184 do \
185 { \
186 (a) += f( (b), (c), (d) ) + X[r] + (k); \
187 (a) = S( (a), (s) ) + (e); \
188 (c) = S( (c), 10 ); \
189 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100190
Hanno Beckerd6028a12018-10-15 12:01:35 +0100191#define P2( a, b, c, d, e, r, s, rp, sp ) \
192 do \
193 { \
194 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
195 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
196 (rp), (sp), Fp, Kp ); \
197 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100198
199#define F F1
200#define K 0x00000000
201#define Fp F5
202#define Kp 0x50A28BE6
203 P2( A, B, C, D, E, 0, 11, 5, 8 );
204 P2( E, A, B, C, D, 1, 14, 14, 9 );
205 P2( D, E, A, B, C, 2, 15, 7, 9 );
206 P2( C, D, E, A, B, 3, 12, 0, 11 );
207 P2( B, C, D, E, A, 4, 5, 9, 13 );
208 P2( A, B, C, D, E, 5, 8, 2, 15 );
209 P2( E, A, B, C, D, 6, 7, 11, 15 );
210 P2( D, E, A, B, C, 7, 9, 4, 5 );
211 P2( C, D, E, A, B, 8, 11, 13, 7 );
212 P2( B, C, D, E, A, 9, 13, 6, 7 );
213 P2( A, B, C, D, E, 10, 14, 15, 8 );
214 P2( E, A, B, C, D, 11, 15, 8, 11 );
215 P2( D, E, A, B, C, 12, 6, 1, 14 );
216 P2( C, D, E, A, B, 13, 7, 10, 14 );
217 P2( B, C, D, E, A, 14, 9, 3, 12 );
218 P2( A, B, C, D, E, 15, 8, 12, 6 );
219#undef F
220#undef K
221#undef Fp
222#undef Kp
223
224#define F F2
225#define K 0x5A827999
226#define Fp F4
227#define Kp 0x5C4DD124
228 P2( E, A, B, C, D, 7, 7, 6, 9 );
229 P2( D, E, A, B, C, 4, 6, 11, 13 );
230 P2( C, D, E, A, B, 13, 8, 3, 15 );
231 P2( B, C, D, E, A, 1, 13, 7, 7 );
232 P2( A, B, C, D, E, 10, 11, 0, 12 );
233 P2( E, A, B, C, D, 6, 9, 13, 8 );
234 P2( D, E, A, B, C, 15, 7, 5, 9 );
235 P2( C, D, E, A, B, 3, 15, 10, 11 );
236 P2( B, C, D, E, A, 12, 7, 14, 7 );
237 P2( A, B, C, D, E, 0, 12, 15, 7 );
238 P2( E, A, B, C, D, 9, 15, 8, 12 );
239 P2( D, E, A, B, C, 5, 9, 12, 7 );
240 P2( C, D, E, A, B, 2, 11, 4, 6 );
241 P2( B, C, D, E, A, 14, 7, 9, 15 );
242 P2( A, B, C, D, E, 11, 13, 1, 13 );
243 P2( E, A, B, C, D, 8, 12, 2, 11 );
244#undef F
245#undef K
246#undef Fp
247#undef Kp
248
249#define F F3
250#define K 0x6ED9EBA1
251#define Fp F3
252#define Kp 0x6D703EF3
253 P2( D, E, A, B, C, 3, 11, 15, 9 );
254 P2( C, D, E, A, B, 10, 13, 5, 7 );
255 P2( B, C, D, E, A, 14, 6, 1, 15 );
256 P2( A, B, C, D, E, 4, 7, 3, 11 );
257 P2( E, A, B, C, D, 9, 14, 7, 8 );
258 P2( D, E, A, B, C, 15, 9, 14, 6 );
259 P2( C, D, E, A, B, 8, 13, 6, 6 );
260 P2( B, C, D, E, A, 1, 15, 9, 14 );
261 P2( A, B, C, D, E, 2, 14, 11, 12 );
262 P2( E, A, B, C, D, 7, 8, 8, 13 );
263 P2( D, E, A, B, C, 0, 13, 12, 5 );
264 P2( C, D, E, A, B, 6, 6, 2, 14 );
265 P2( B, C, D, E, A, 13, 5, 10, 13 );
266 P2( A, B, C, D, E, 11, 12, 0, 13 );
267 P2( E, A, B, C, D, 5, 7, 4, 7 );
268 P2( D, E, A, B, C, 12, 5, 13, 5 );
269#undef F
270#undef K
271#undef Fp
272#undef Kp
273
274#define F F4
275#define K 0x8F1BBCDC
276#define Fp F2
277#define Kp 0x7A6D76E9
278 P2( C, D, E, A, B, 1, 11, 8, 15 );
279 P2( B, C, D, E, A, 9, 12, 6, 5 );
280 P2( A, B, C, D, E, 11, 14, 4, 8 );
281 P2( E, A, B, C, D, 10, 15, 1, 11 );
282 P2( D, E, A, B, C, 0, 14, 3, 14 );
283 P2( C, D, E, A, B, 8, 15, 11, 14 );
284 P2( B, C, D, E, A, 12, 9, 15, 6 );
285 P2( A, B, C, D, E, 4, 8, 0, 14 );
286 P2( E, A, B, C, D, 13, 9, 5, 6 );
287 P2( D, E, A, B, C, 3, 14, 12, 9 );
288 P2( C, D, E, A, B, 7, 5, 2, 12 );
289 P2( B, C, D, E, A, 15, 6, 13, 9 );
290 P2( A, B, C, D, E, 14, 8, 9, 12 );
291 P2( E, A, B, C, D, 5, 6, 7, 5 );
292 P2( D, E, A, B, C, 6, 5, 10, 15 );
293 P2( C, D, E, A, B, 2, 12, 14, 8 );
294#undef F
295#undef K
296#undef Fp
297#undef Kp
298
299#define F F5
300#define K 0xA953FD4E
301#define Fp F1
302#define Kp 0x00000000
303 P2( B, C, D, E, A, 4, 9, 12, 8 );
304 P2( A, B, C, D, E, 0, 15, 15, 5 );
305 P2( E, A, B, C, D, 5, 5, 10, 12 );
306 P2( D, E, A, B, C, 9, 11, 4, 9 );
307 P2( C, D, E, A, B, 7, 6, 1, 12 );
308 P2( B, C, D, E, A, 12, 8, 5, 5 );
309 P2( A, B, C, D, E, 2, 13, 8, 14 );
310 P2( E, A, B, C, D, 10, 12, 7, 6 );
311 P2( D, E, A, B, C, 14, 5, 6, 8 );
312 P2( C, D, E, A, B, 1, 12, 2, 13 );
313 P2( B, C, D, E, A, 3, 13, 13, 6 );
314 P2( A, B, C, D, E, 8, 14, 14, 5 );
315 P2( E, A, B, C, D, 11, 11, 0, 15 );
316 P2( D, E, A, B, C, 6, 8, 3, 13 );
317 P2( C, D, E, A, B, 15, 5, 9, 11 );
318 P2( B, C, D, E, A, 13, 6, 11, 11 );
319#undef F
320#undef K
321#undef Fp
322#undef Kp
323
324 C = ctx->state[1] + C + Dp;
325 ctx->state[1] = ctx->state[2] + D + Ep;
326 ctx->state[2] = ctx->state[3] + E + Ap;
327 ctx->state[3] = ctx->state[4] + A + Bp;
328 ctx->state[4] = ctx->state[0] + B + Cp;
329 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100330
gabor-mezei-armf21639f2020-08-19 14:03:06 +0200331 /* Zeroise variables to clear sensitive data from memory. */
332 mbedtls_platform_zeroize( &A, sizeof( A ) );
333 mbedtls_platform_zeroize( &B, sizeof( B ) );
334 mbedtls_platform_zeroize( &C, sizeof( C ) );
335 mbedtls_platform_zeroize( &D, sizeof( D ) );
336 mbedtls_platform_zeroize( &E, sizeof( E ) );
337 mbedtls_platform_zeroize( &Ap, sizeof( Ap ) );
338 mbedtls_platform_zeroize( &Bp, sizeof( Bp ) );
339 mbedtls_platform_zeroize( &Cp, sizeof( Cp ) );
340 mbedtls_platform_zeroize( &Dp, sizeof( Dp ) );
341 mbedtls_platform_zeroize( &Ep, sizeof( Ep ) );
342 mbedtls_platform_zeroize( &X, sizeof( X ) );
343
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100344 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100345}
Jaeden Amero041039f2018-02-19 15:28:08 +0000346
347#if !defined(MBEDTLS_DEPRECATED_REMOVED)
348void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
349 const unsigned char data[64] )
350{
351 mbedtls_internal_ripemd160_process( ctx, data );
352}
353#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100355
356/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100357 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100358 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100359int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100360 const unsigned char *input,
361 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100362{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100363 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364 size_t fill;
365 uint32_t left;
366
Brian White12895d12014-04-11 11:29:42 -0400367 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100368 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100369
370 left = ctx->total[0] & 0x3F;
371 fill = 64 - left;
372
373 ctx->total[0] += (uint32_t) ilen;
374 ctx->total[0] &= 0xFFFFFFFF;
375
376 if( ctx->total[0] < (uint32_t) ilen )
377 ctx->total[1]++;
378
379 if( left && ilen >= fill )
380 {
381 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100382
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100383 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100384 return( ret );
385
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100386 input += fill;
387 ilen -= fill;
388 left = 0;
389 }
390
391 while( ilen >= 64 )
392 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100393 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100394 return( ret );
395
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100396 input += 64;
397 ilen -= 64;
398 }
399
400 if( ilen > 0 )
401 {
402 memcpy( (void *) (ctx->buffer + left), input, ilen );
403 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100404
405 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406}
407
Jaeden Amero041039f2018-02-19 15:28:08 +0000408#if !defined(MBEDTLS_DEPRECATED_REMOVED)
409void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
410 const unsigned char *input,
411 size_t ilen )
412{
413 mbedtls_ripemd160_update_ret( ctx, input, ilen );
414}
415#endif
416
Paul Bakker61b699e2014-01-22 13:35:29 +0100417static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100418{
419 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
420 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
421 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
422 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
423};
424
425/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100426 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100427 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100428int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100429 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100430{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100431 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100432 uint32_t last, padn;
433 uint32_t high, low;
434 unsigned char msglen[8];
435
436 high = ( ctx->total[0] >> 29 )
437 | ( ctx->total[1] << 3 );
438 low = ( ctx->total[0] << 3 );
439
440 PUT_UINT32_LE( low, msglen, 0 );
441 PUT_UINT32_LE( high, msglen, 4 );
442
443 last = ctx->total[0] & 0x3F;
444 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
445
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100446 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100447 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100448 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100449
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100450 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100451 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100452 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100453
454 PUT_UINT32_LE( ctx->state[0], output, 0 );
455 PUT_UINT32_LE( ctx->state[1], output, 4 );
456 PUT_UINT32_LE( ctx->state[2], output, 8 );
457 PUT_UINT32_LE( ctx->state[3], output, 12 );
458 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100459
460 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100461}
462
Jaeden Amero041039f2018-02-19 15:28:08 +0000463#if !defined(MBEDTLS_DEPRECATED_REMOVED)
464void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
465 unsigned char output[20] )
466{
467 mbedtls_ripemd160_finish_ret( ctx, output );
468}
469#endif
470
Gilles Peskine342d9282018-01-23 18:21:21 +0100471#endif /* ! MBEDTLS_RIPEMD160_ALT */
472
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100473/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100474 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100476int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100477 size_t ilen,
478 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100479{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100480 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100484
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100485 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100486 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100487
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100488 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100489 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100490
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100491 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100492 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100493
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100494exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100496
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100497 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100498}
499
Jaeden Amero041039f2018-02-19 15:28:08 +0000500#if !defined(MBEDTLS_DEPRECATED_REMOVED)
501void mbedtls_ripemd160( const unsigned char *input,
502 size_t ilen,
503 unsigned char output[20] )
504{
505 mbedtls_ripemd160_ret( input, ilen, output );
506}
507#endif
508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100510/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100511 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100513 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100514#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100515static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100516{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100517 { "" },
518 { "a" },
519 { "abc" },
520 { "message digest" },
521 { "abcdefghijklmnopqrstuvwxyz" },
522 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
523 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
524 { "12345678901234567890123456789012345678901234567890123456789012"
525 "345678901234567890" },
526};
527
528static const size_t ripemd160_test_strlen[TESTS] =
529{
530 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100531};
532
Paul Bakker61b699e2014-01-22 13:35:29 +0100533static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100534{
535 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
536 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
537 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
538 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
539 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
540 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
541 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
542 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
543 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
544 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
545 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
546 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
547 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
548 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
549 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
550 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
551};
552
553/*
554 * Checkup routine
555 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100557{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100558 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100559 unsigned char output[20];
560
561 memset( output, 0, sizeof output );
562
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100563 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100564 {
565 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100567
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100568 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100569 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100570 if( ret != 0 )
571 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100572
Paul Bakker61b699e2014-01-22 13:35:29 +0100573 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100574 {
575 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100576 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100577 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100578
579 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100581 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100582
Paul Bakker4400ecc2016-07-19 14:41:43 +0100583 if( verbose != 0 )
584 mbedtls_printf( "\n" );
585
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100586 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100587
588fail:
589 if( verbose != 0 )
590 mbedtls_printf( "failed\n" );
591
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100592 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100593}
594
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100596
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597#endif /* MBEDTLS_RIPEMD160_C */