blob: ae4dee4121db4a29c98a87788c19840aed4a51b9 [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
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200106#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{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200120 struct
121 {
122 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
123 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100124
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200125 GET_UINT32_LE( local.X[ 0], data, 0 );
126 GET_UINT32_LE( local.X[ 1], data, 4 );
127 GET_UINT32_LE( local.X[ 2], data, 8 );
128 GET_UINT32_LE( local.X[ 3], data, 12 );
129 GET_UINT32_LE( local.X[ 4], data, 16 );
130 GET_UINT32_LE( local.X[ 5], data, 20 );
131 GET_UINT32_LE( local.X[ 6], data, 24 );
132 GET_UINT32_LE( local.X[ 7], data, 28 );
133 GET_UINT32_LE( local.X[ 8], data, 32 );
134 GET_UINT32_LE( local.X[ 9], data, 36 );
135 GET_UINT32_LE( local.X[10], data, 40 );
136 GET_UINT32_LE( local.X[11], data, 44 );
137 GET_UINT32_LE( local.X[12], data, 48 );
138 GET_UINT32_LE( local.X[13], data, 52 );
139 GET_UINT32_LE( local.X[14], data, 56 );
140 GET_UINT32_LE( local.X[15], data, 60 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100141
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200142 local.A = local.Ap = ctx->state[0];
143 local.B = local.Bp = ctx->state[1];
144 local.C = local.Cp = ctx->state[2];
145 local.D = local.Dp = ctx->state[3];
146 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100147
Hanno Becker1eeca412018-10-15 12:01:35 +0100148#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
149#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
150#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
151#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
152#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100153
Hanno Becker1eeca412018-10-15 12:01:35 +0100154#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100155
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200156#define P( a, b, c, d, e, r, s, f, k ) \
157 do \
158 { \
159 (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
160 (a) = S( (a), (s) ) + (e); \
161 (c) = S( (c), 10 ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100162 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100163
Hanno Becker1eeca412018-10-15 12:01:35 +0100164#define P2( a, b, c, d, e, r, s, rp, sp ) \
165 do \
166 { \
167 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
168 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
169 (rp), (sp), Fp, Kp ); \
170 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100171
172#define F F1
173#define K 0x00000000
174#define Fp F5
175#define Kp 0x50A28BE6
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200176 P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
177 P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
178 P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
179 P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
180 P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
181 P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
182 P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
183 P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
184 P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
185 P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
186 P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
187 P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
188 P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
189 P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
190 P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
191 P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100192#undef F
193#undef K
194#undef Fp
195#undef Kp
196
197#define F F2
198#define K 0x5A827999
199#define Fp F4
200#define Kp 0x5C4DD124
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200201 P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
202 P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
203 P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
204 P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
205 P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
206 P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
207 P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
208 P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
209 P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
210 P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
211 P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
212 P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
213 P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
214 P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
215 P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
216 P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100217#undef F
218#undef K
219#undef Fp
220#undef Kp
221
222#define F F3
223#define K 0x6ED9EBA1
224#define Fp F3
225#define Kp 0x6D703EF3
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200226 P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
227 P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
228 P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
229 P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
230 P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
231 P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
232 P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
233 P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
234 P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
235 P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
236 P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
237 P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
238 P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
239 P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
240 P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
241 P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100242#undef F
243#undef K
244#undef Fp
245#undef Kp
246
247#define F F4
248#define K 0x8F1BBCDC
249#define Fp F2
250#define Kp 0x7A6D76E9
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200251 P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
252 P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
253 P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
254 P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
255 P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
256 P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
257 P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
258 P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
259 P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
260 P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
261 P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
262 P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
263 P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
264 P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
265 P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
266 P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100267#undef F
268#undef K
269#undef Fp
270#undef Kp
271
272#define F F5
273#define K 0xA953FD4E
274#define Fp F1
275#define Kp 0x00000000
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200276 P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
277 P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
278 P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
279 P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
280 P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
281 P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
282 P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
283 P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
284 P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
285 P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
286 P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
287 P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
288 P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
289 P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
290 P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
291 P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100292#undef F
293#undef K
294#undef Fp
295#undef Kp
296
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200297 local.C = ctx->state[1] + local.C + local.Dp;
298 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
299 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
300 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
301 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
302 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100303
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200304 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200305 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100306
307 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100308}
Jaeden Amero041039f2018-02-19 15:28:08 +0000309
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200310#if !defined(MBEDTLS_DEPRECATED_REMOVED)
311void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
312 const unsigned char data[64] )
313{
314 mbedtls_internal_ripemd160_process( ctx, data );
315}
316#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100318
319/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100320 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100321 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100322int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100323 const unsigned char *input,
324 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100325{
Janos Follath24eed8d2019-11-22 13:21:35 +0000326 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100327 size_t fill;
328 uint32_t left;
329
Brian White12895d12014-04-11 11:29:42 -0400330 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100331 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100332
333 left = ctx->total[0] & 0x3F;
334 fill = 64 - left;
335
336 ctx->total[0] += (uint32_t) ilen;
337 ctx->total[0] &= 0xFFFFFFFF;
338
339 if( ctx->total[0] < (uint32_t) ilen )
340 ctx->total[1]++;
341
342 if( left && ilen >= fill )
343 {
344 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100345
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100346 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100347 return( ret );
348
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100349 input += fill;
350 ilen -= fill;
351 left = 0;
352 }
353
354 while( ilen >= 64 )
355 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100356 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100357 return( ret );
358
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100359 input += 64;
360 ilen -= 64;
361 }
362
363 if( ilen > 0 )
364 {
365 memcpy( (void *) (ctx->buffer + left), input, ilen );
366 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100367
368 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100369}
370
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200371#if !defined(MBEDTLS_DEPRECATED_REMOVED)
372void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
373 const unsigned char *input,
374 size_t ilen )
375{
376 mbedtls_ripemd160_update_ret( ctx, input, ilen );
377}
378#endif
379
Paul Bakker61b699e2014-01-22 13:35:29 +0100380static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100381{
382 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
383 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
384 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
386};
387
388/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100389 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100390 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100391int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100392 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100393{
Janos Follath24eed8d2019-11-22 13:21:35 +0000394 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100395 uint32_t last, padn;
396 uint32_t high, low;
397 unsigned char msglen[8];
398
399 high = ( ctx->total[0] >> 29 )
400 | ( ctx->total[1] << 3 );
401 low = ( ctx->total[0] << 3 );
402
403 PUT_UINT32_LE( low, msglen, 0 );
404 PUT_UINT32_LE( high, msglen, 4 );
405
406 last = ctx->total[0] & 0x3F;
407 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
408
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100409 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100410 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100411 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100412
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100413 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100414 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100415 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100416
417 PUT_UINT32_LE( ctx->state[0], output, 0 );
418 PUT_UINT32_LE( ctx->state[1], output, 4 );
419 PUT_UINT32_LE( ctx->state[2], output, 8 );
420 PUT_UINT32_LE( ctx->state[3], output, 12 );
421 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100422
423 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100424}
425
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200426#if !defined(MBEDTLS_DEPRECATED_REMOVED)
427void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
428 unsigned char output[20] )
429{
430 mbedtls_ripemd160_finish_ret( ctx, output );
431}
432#endif
433
Gilles Peskine342d9282018-01-23 18:21:21 +0100434#endif /* ! MBEDTLS_RIPEMD160_ALT */
435
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100436/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100437 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100438 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100439int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100440 size_t ilen,
441 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100442{
Janos Follath24eed8d2019-11-22 13:21:35 +0000443 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100447
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100448 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100449 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100450
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100451 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100452 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100453
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100454 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100455 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100456
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100457exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100459
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100460 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100461}
462
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200463#if !defined(MBEDTLS_DEPRECATED_REMOVED)
464void mbedtls_ripemd160( const unsigned char *input,
465 size_t ilen,
466 unsigned char output[20] )
467{
468 mbedtls_ripemd160_ret( input, ilen, output );
469}
470#endif
471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100473/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100474 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100476 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100477#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100478static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100479{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100480 { "" },
481 { "a" },
482 { "abc" },
483 { "message digest" },
484 { "abcdefghijklmnopqrstuvwxyz" },
485 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
486 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200487 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100488};
489
490static const size_t ripemd160_test_strlen[TESTS] =
491{
492 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100493};
494
Paul Bakker61b699e2014-01-22 13:35:29 +0100495static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100496{
497 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
498 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
499 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
500 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
501 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
502 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
503 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
504 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
505 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
506 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
507 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
508 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
509 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
510 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
511 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
512 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
513};
514
515/*
516 * Checkup routine
517 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100519{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100520 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100521 unsigned char output[20];
522
523 memset( output, 0, sizeof output );
524
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100525 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100526 {
527 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100529
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100530 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100531 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100532 if( ret != 0 )
533 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100534
Paul Bakker61b699e2014-01-22 13:35:29 +0100535 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100536 {
537 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100538 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100539 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100540
541 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100543 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100544
Paul Bakker4400ecc2016-07-19 14:41:43 +0100545 if( verbose != 0 )
546 mbedtls_printf( "\n" );
547
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100548 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100549
550fail:
551 if( verbose != 0 )
552 mbedtls_printf( "failed\n" );
553
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100554 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100555}
556
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100558
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559#endif /* MBEDTLS_RIPEMD160_C */