blob: d2ccbbec47e501df57a998aedee2a17fcb32cb1e [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 */
TRodziewicz26371e42021-06-08 16:45:41 +020092int mbedtls_ripemd160_starts( 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é-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100107/*
108 * Process one block
109 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100110int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
111 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100112{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200113 struct
114 {
115 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
116 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100117
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200118 GET_UINT32_LE( local.X[ 0], data, 0 );
119 GET_UINT32_LE( local.X[ 1], data, 4 );
120 GET_UINT32_LE( local.X[ 2], data, 8 );
121 GET_UINT32_LE( local.X[ 3], data, 12 );
122 GET_UINT32_LE( local.X[ 4], data, 16 );
123 GET_UINT32_LE( local.X[ 5], data, 20 );
124 GET_UINT32_LE( local.X[ 6], data, 24 );
125 GET_UINT32_LE( local.X[ 7], data, 28 );
126 GET_UINT32_LE( local.X[ 8], data, 32 );
127 GET_UINT32_LE( local.X[ 9], data, 36 );
128 GET_UINT32_LE( local.X[10], data, 40 );
129 GET_UINT32_LE( local.X[11], data, 44 );
130 GET_UINT32_LE( local.X[12], data, 48 );
131 GET_UINT32_LE( local.X[13], data, 52 );
132 GET_UINT32_LE( local.X[14], data, 56 );
133 GET_UINT32_LE( local.X[15], data, 60 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100134
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200135 local.A = local.Ap = ctx->state[0];
136 local.B = local.Bp = ctx->state[1];
137 local.C = local.Cp = ctx->state[2];
138 local.D = local.Dp = ctx->state[3];
139 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100140
Hanno Becker1eeca412018-10-15 12:01:35 +0100141#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
142#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
143#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
144#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
145#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100146
Hanno Becker1eeca412018-10-15 12:01:35 +0100147#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100148
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200149#define P( a, b, c, d, e, r, s, f, k ) \
150 do \
151 { \
152 (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
153 (a) = S( (a), (s) ) + (e); \
154 (c) = S( (c), 10 ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100155 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100156
Hanno Becker1eeca412018-10-15 12:01:35 +0100157#define P2( a, b, c, d, e, r, s, rp, sp ) \
158 do \
159 { \
160 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
161 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
162 (rp), (sp), Fp, Kp ); \
163 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100164
165#define F F1
166#define K 0x00000000
167#define Fp F5
168#define Kp 0x50A28BE6
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200169 P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
170 P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
171 P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
172 P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
173 P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
174 P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
175 P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
176 P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
177 P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
178 P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
179 P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
180 P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
181 P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
182 P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
183 P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
184 P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100185#undef F
186#undef K
187#undef Fp
188#undef Kp
189
190#define F F2
191#define K 0x5A827999
192#define Fp F4
193#define Kp 0x5C4DD124
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200194 P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
195 P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
196 P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
197 P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
198 P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
199 P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
200 P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
201 P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
202 P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
203 P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
204 P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
205 P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
206 P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
207 P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
208 P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
209 P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100210#undef F
211#undef K
212#undef Fp
213#undef Kp
214
215#define F F3
216#define K 0x6ED9EBA1
217#define Fp F3
218#define Kp 0x6D703EF3
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200219 P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
220 P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
221 P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
222 P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
223 P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
224 P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
225 P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
226 P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
227 P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
228 P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
229 P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
230 P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
231 P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
232 P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
233 P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
234 P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100235#undef F
236#undef K
237#undef Fp
238#undef Kp
239
240#define F F4
241#define K 0x8F1BBCDC
242#define Fp F2
243#define Kp 0x7A6D76E9
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200244 P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
245 P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
246 P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
247 P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
248 P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
249 P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
250 P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
251 P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
252 P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
253 P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
254 P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
255 P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
256 P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
257 P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
258 P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
259 P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100260#undef F
261#undef K
262#undef Fp
263#undef Kp
264
265#define F F5
266#define K 0xA953FD4E
267#define Fp F1
268#define Kp 0x00000000
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200269 P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
270 P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
271 P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
272 P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
273 P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
274 P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
275 P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
276 P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
277 P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
278 P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
279 P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
280 P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
281 P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
282 P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
283 P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
284 P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100285#undef F
286#undef K
287#undef Fp
288#undef Kp
289
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200290 local.C = ctx->state[1] + local.C + local.Dp;
291 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
292 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
293 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
294 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
295 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100296
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200297 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200298 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100299
300 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100301}
Jaeden Amero041039f2018-02-19 15:28:08 +0000302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100304
305/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100306 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100307 */
TRodziewicz26371e42021-06-08 16:45:41 +0200308int mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100309 const unsigned char *input,
310 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100311{
Janos Follath24eed8d2019-11-22 13:21:35 +0000312 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100313 size_t fill;
314 uint32_t left;
315
Brian White12895d12014-04-11 11:29:42 -0400316 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100317 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100318
319 left = ctx->total[0] & 0x3F;
320 fill = 64 - left;
321
322 ctx->total[0] += (uint32_t) ilen;
323 ctx->total[0] &= 0xFFFFFFFF;
324
325 if( ctx->total[0] < (uint32_t) ilen )
326 ctx->total[1]++;
327
328 if( left && ilen >= fill )
329 {
330 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100331
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100332 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100333 return( ret );
334
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100335 input += fill;
336 ilen -= fill;
337 left = 0;
338 }
339
340 while( ilen >= 64 )
341 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100342 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100343 return( ret );
344
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100345 input += 64;
346 ilen -= 64;
347 }
348
349 if( ilen > 0 )
350 {
351 memcpy( (void *) (ctx->buffer + left), input, ilen );
352 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100353
354 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100355}
356
Paul Bakker61b699e2014-01-22 13:35:29 +0100357static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100358{
359 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
360 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
361 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
362 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
363};
364
365/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100366 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100367 */
TRodziewicz26371e42021-06-08 16:45:41 +0200368int mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100369 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100370{
Janos Follath24eed8d2019-11-22 13:21:35 +0000371 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372 uint32_t last, padn;
373 uint32_t high, low;
374 unsigned char msglen[8];
375
376 high = ( ctx->total[0] >> 29 )
377 | ( ctx->total[1] << 3 );
378 low = ( ctx->total[0] << 3 );
379
380 PUT_UINT32_LE( low, msglen, 0 );
381 PUT_UINT32_LE( high, msglen, 4 );
382
383 last = ctx->total[0] & 0x3F;
384 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
385
TRodziewicz26371e42021-06-08 16:45:41 +0200386 ret = mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100387 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100388 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100389
TRodziewicz26371e42021-06-08 16:45:41 +0200390 ret = mbedtls_ripemd160_update( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100391 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100392 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100393
394 PUT_UINT32_LE( ctx->state[0], output, 0 );
395 PUT_UINT32_LE( ctx->state[1], output, 4 );
396 PUT_UINT32_LE( ctx->state[2], output, 8 );
397 PUT_UINT32_LE( ctx->state[3], output, 12 );
398 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100399
400 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100401}
402
Gilles Peskine342d9282018-01-23 18:21:21 +0100403#endif /* ! MBEDTLS_RIPEMD160_ALT */
404
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100405/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100406 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100407 */
TRodziewicz26371e42021-06-08 16:45:41 +0200408int mbedtls_ripemd160( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100409 size_t ilen,
410 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100411{
Janos Follath24eed8d2019-11-22 13:21:35 +0000412 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100414
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100416
TRodziewicz26371e42021-06-08 16:45:41 +0200417 if( ( ret = mbedtls_ripemd160_starts( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100418 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100419
TRodziewicz26371e42021-06-08 16:45:41 +0200420 if( ( ret = mbedtls_ripemd160_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100421 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100422
TRodziewicz26371e42021-06-08 16:45:41 +0200423 if( ( ret = mbedtls_ripemd160_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100424 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100425
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100426exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100428
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100429 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100430}
431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100433/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100434 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100436 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100437#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100438static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100439{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100440 { "" },
441 { "a" },
442 { "abc" },
443 { "message digest" },
444 { "abcdefghijklmnopqrstuvwxyz" },
445 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
446 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200447 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100448};
449
450static const size_t ripemd160_test_strlen[TESTS] =
451{
452 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100453};
454
Paul Bakker61b699e2014-01-22 13:35:29 +0100455static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100456{
457 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
458 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
459 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
460 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
461 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
462 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
463 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
464 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
465 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
466 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
467 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
468 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
469 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
470 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
471 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
472 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
473};
474
475/*
476 * Checkup routine
477 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100479{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100480 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100481 unsigned char output[20];
482
483 memset( output, 0, sizeof output );
484
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100485 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100486 {
487 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100489
TRodziewicz26371e42021-06-08 16:45:41 +0200490 ret = mbedtls_ripemd160( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100491 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100492 if( ret != 0 )
493 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100494
Paul Bakker61b699e2014-01-22 13:35:29 +0100495 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100496 {
497 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100498 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100499 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100500
501 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100503 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100504
Paul Bakker4400ecc2016-07-19 14:41:43 +0100505 if( verbose != 0 )
506 mbedtls_printf( "\n" );
507
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100508 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100509
510fail:
511 if( verbose != 0 )
512 mbedtls_printf( "failed\n" );
513
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100514 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100515}
516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519#endif /* MBEDTLS_RIPEMD160_C */