blob: c090c8f9d215ca117d68ad57f64f83113b20d0a2 [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{
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200150 struct
151 {
152 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
153 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100154
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200155 GET_UINT32_LE( local.X[ 0], data, 0 );
156 GET_UINT32_LE( local.X[ 1], data, 4 );
157 GET_UINT32_LE( local.X[ 2], data, 8 );
158 GET_UINT32_LE( local.X[ 3], data, 12 );
159 GET_UINT32_LE( local.X[ 4], data, 16 );
160 GET_UINT32_LE( local.X[ 5], data, 20 );
161 GET_UINT32_LE( local.X[ 6], data, 24 );
162 GET_UINT32_LE( local.X[ 7], data, 28 );
163 GET_UINT32_LE( local.X[ 8], data, 32 );
164 GET_UINT32_LE( local.X[ 9], data, 36 );
165 GET_UINT32_LE( local.X[10], data, 40 );
166 GET_UINT32_LE( local.X[11], data, 44 );
167 GET_UINT32_LE( local.X[12], data, 48 );
168 GET_UINT32_LE( local.X[13], data, 52 );
169 GET_UINT32_LE( local.X[14], data, 56 );
170 GET_UINT32_LE( local.X[15], data, 60 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100171
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200172 local.A = local.Ap = ctx->state[0];
173 local.B = local.Bp = ctx->state[1];
174 local.C = local.Cp = ctx->state[2];
175 local.D = local.Dp = ctx->state[3];
176 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100177
Hanno Beckerd6028a12018-10-15 12:01:35 +0100178#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
179#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
180#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
181#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
182#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100183
Hanno Beckerd6028a12018-10-15 12:01:35 +0100184#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100185
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200186#define P( a, b, c, d, e, r, s, f, k ) \
187 do \
188 { \
189 (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
190 (a) = S( (a), (s) ) + (e); \
191 (c) = S( (c), 10 ); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100192 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100193
Hanno Beckerd6028a12018-10-15 12:01:35 +0100194#define P2( a, b, c, d, e, r, s, rp, sp ) \
195 do \
196 { \
197 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
198 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
199 (rp), (sp), Fp, Kp ); \
200 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100201
202#define F F1
203#define K 0x00000000
204#define Fp F5
205#define Kp 0x50A28BE6
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200206 P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
207 P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
208 P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
209 P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
210 P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
211 P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
212 P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
213 P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
214 P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
215 P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
216 P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
217 P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
218 P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
219 P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
220 P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
221 P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100222#undef F
223#undef K
224#undef Fp
225#undef Kp
226
227#define F F2
228#define K 0x5A827999
229#define Fp F4
230#define Kp 0x5C4DD124
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200231 P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
232 P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
233 P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
234 P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
235 P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
236 P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
237 P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
238 P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
239 P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
240 P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
241 P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
242 P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
243 P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
244 P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
245 P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
246 P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100247#undef F
248#undef K
249#undef Fp
250#undef Kp
251
252#define F F3
253#define K 0x6ED9EBA1
254#define Fp F3
255#define Kp 0x6D703EF3
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200256 P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
257 P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
258 P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
259 P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
260 P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
261 P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
262 P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
263 P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
264 P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
265 P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
266 P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
267 P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
268 P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
269 P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
270 P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
271 P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100272#undef F
273#undef K
274#undef Fp
275#undef Kp
276
277#define F F4
278#define K 0x8F1BBCDC
279#define Fp F2
280#define Kp 0x7A6D76E9
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200281 P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
282 P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
283 P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
284 P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
285 P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
286 P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
287 P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
288 P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
289 P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
290 P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
291 P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
292 P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
293 P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
294 P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
295 P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
296 P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297#undef F
298#undef K
299#undef Fp
300#undef Kp
301
302#define F F5
303#define K 0xA953FD4E
304#define Fp F1
305#define Kp 0x00000000
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200306 P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
307 P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
308 P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
309 P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
310 P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
311 P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
312 P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
313 P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
314 P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
315 P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
316 P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
317 P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
318 P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
319 P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
320 P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
321 P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100322#undef F
323#undef K
324#undef Fp
325#undef Kp
326
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200327 local.C = ctx->state[1] + local.C + local.Dp;
328 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
329 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
330 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
331 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
332 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100333
gabor-mezei-armf21639f2020-08-19 14:03:06 +0200334 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200335 mbedtls_platform_zeroize( &local, sizeof( local ) );
gabor-mezei-armf21639f2020-08-19 14:03:06 +0200336
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100337 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100338}
Jaeden Amero041039f2018-02-19 15:28:08 +0000339
340#if !defined(MBEDTLS_DEPRECATED_REMOVED)
341void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
342 const unsigned char data[64] )
343{
344 mbedtls_internal_ripemd160_process( ctx, data );
345}
346#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100348
349/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100350 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100351 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100352int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100353 const unsigned char *input,
354 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100355{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100356 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100357 size_t fill;
358 uint32_t left;
359
Brian White12895d12014-04-11 11:29:42 -0400360 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100361 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100362
363 left = ctx->total[0] & 0x3F;
364 fill = 64 - left;
365
366 ctx->total[0] += (uint32_t) ilen;
367 ctx->total[0] &= 0xFFFFFFFF;
368
369 if( ctx->total[0] < (uint32_t) ilen )
370 ctx->total[1]++;
371
372 if( left && ilen >= fill )
373 {
374 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100375
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100376 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100377 return( ret );
378
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100379 input += fill;
380 ilen -= fill;
381 left = 0;
382 }
383
384 while( ilen >= 64 )
385 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100386 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100387 return( ret );
388
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100389 input += 64;
390 ilen -= 64;
391 }
392
393 if( ilen > 0 )
394 {
395 memcpy( (void *) (ctx->buffer + left), input, ilen );
396 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100397
398 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100399}
400
Jaeden Amero041039f2018-02-19 15:28:08 +0000401#if !defined(MBEDTLS_DEPRECATED_REMOVED)
402void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
403 const unsigned char *input,
404 size_t ilen )
405{
406 mbedtls_ripemd160_update_ret( ctx, input, ilen );
407}
408#endif
409
Paul Bakker61b699e2014-01-22 13:35:29 +0100410static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100411{
412 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
413 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
414 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
415 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
416};
417
418/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100419 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100420 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100421int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100422 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100423{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100424 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100425 uint32_t last, padn;
426 uint32_t high, low;
427 unsigned char msglen[8];
428
429 high = ( ctx->total[0] >> 29 )
430 | ( ctx->total[1] << 3 );
431 low = ( ctx->total[0] << 3 );
432
433 PUT_UINT32_LE( low, msglen, 0 );
434 PUT_UINT32_LE( high, msglen, 4 );
435
436 last = ctx->total[0] & 0x3F;
437 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
438
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100439 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100440 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100441 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100442
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100443 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100444 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100445 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100446
447 PUT_UINT32_LE( ctx->state[0], output, 0 );
448 PUT_UINT32_LE( ctx->state[1], output, 4 );
449 PUT_UINT32_LE( ctx->state[2], output, 8 );
450 PUT_UINT32_LE( ctx->state[3], output, 12 );
451 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100452
453 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100454}
455
Jaeden Amero041039f2018-02-19 15:28:08 +0000456#if !defined(MBEDTLS_DEPRECATED_REMOVED)
457void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
458 unsigned char output[20] )
459{
460 mbedtls_ripemd160_finish_ret( ctx, output );
461}
462#endif
463
Gilles Peskine342d9282018-01-23 18:21:21 +0100464#endif /* ! MBEDTLS_RIPEMD160_ALT */
465
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100466/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100467 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100468 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100469int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100470 size_t ilen,
471 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100472{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100473 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100477
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100478 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100479 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100480
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100481 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100482 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100483
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100484 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100485 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100486
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100487exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100489
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100490 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100491}
492
Jaeden Amero041039f2018-02-19 15:28:08 +0000493#if !defined(MBEDTLS_DEPRECATED_REMOVED)
494void mbedtls_ripemd160( const unsigned char *input,
495 size_t ilen,
496 unsigned char output[20] )
497{
498 mbedtls_ripemd160_ret( input, ilen, output );
499}
500#endif
501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100503/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100504 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100506 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100507#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100508static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100509{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100510 { "" },
511 { "a" },
512 { "abc" },
513 { "message digest" },
514 { "abcdefghijklmnopqrstuvwxyz" },
515 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
516 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken70bdf8d2020-08-21 21:08:56 +0200517 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100518};
519
520static const size_t ripemd160_test_strlen[TESTS] =
521{
522 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100523};
524
Paul Bakker61b699e2014-01-22 13:35:29 +0100525static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100526{
527 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
528 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
529 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
530 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
531 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
532 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
533 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
534 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
535 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
536 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
537 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
538 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
539 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
540 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
541 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
542 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
543};
544
545/*
546 * Checkup routine
547 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200548int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100549{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100550 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100551 unsigned char output[20];
552
553 memset( output, 0, sizeof output );
554
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100555 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100556 {
557 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100559
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100560 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100561 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100562 if( ret != 0 )
563 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100564
Paul Bakker61b699e2014-01-22 13:35:29 +0100565 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100566 {
567 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100568 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100569 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100570
571 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100573 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100574
Paul Bakker4400ecc2016-07-19 14:41:43 +0100575 if( verbose != 0 )
576 mbedtls_printf( "\n" );
577
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100578 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100579
580fail:
581 if( verbose != 0 )
582 mbedtls_printf( "failed\n" );
583
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100584 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100585}
586
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100588
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589#endif /* MBEDTLS_RIPEMD160_C */