blob: 6212cb2572df09b6ba2fceb72f46381463b75e29 [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é-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010037
Gilles Peskine342d9282018-01-23 18:21:21 +010038#if !defined(MBEDTLS_RIPEMD160_ALT)
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020041{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020043}
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020046{
47 if( ctx == NULL )
48 return;
49
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050050 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020051}
52
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020053void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
54 const mbedtls_ripemd160_context *src )
55{
56 *dst = *src;
57}
58
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010059/*
Paul Bakker61b699e2014-01-22 13:35:29 +010060 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010061 */
TRodziewicz26371e42021-06-08 16:45:41 +020062int mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010063{
64 ctx->total[0] = 0;
65 ctx->total[1] = 0;
66
67 ctx->state[0] = 0x67452301;
68 ctx->state[1] = 0xEFCDAB89;
69 ctx->state[2] = 0x98BADCFE;
70 ctx->state[3] = 0x10325476;
71 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +010072
73 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010074}
75
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010077/*
78 * Process one block
79 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +010080int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
81 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010082{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020083 struct
84 {
85 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
86 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010087
Joe Subbiani6a506312021-07-07 16:56:29 +010088 local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
89 local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
90 local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
91 local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
92 local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
93 local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
94 local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
95 local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
96 local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
97 local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
98 local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
99 local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
100 local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
101 local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
102 local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
103 local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100104
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200105 local.A = local.Ap = ctx->state[0];
106 local.B = local.Bp = ctx->state[1];
107 local.C = local.Cp = ctx->state[2];
108 local.D = local.Dp = ctx->state[3];
109 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100110
Hanno Becker1eeca412018-10-15 12:01:35 +0100111#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
112#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
113#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
114#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
115#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100116
Hanno Becker1eeca412018-10-15 12:01:35 +0100117#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100118
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200119#define P( a, b, c, d, e, r, s, f, k ) \
120 do \
121 { \
122 (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
123 (a) = S( (a), (s) ) + (e); \
124 (c) = S( (c), 10 ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100125 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100126
Hanno Becker1eeca412018-10-15 12:01:35 +0100127#define P2( a, b, c, d, e, r, s, rp, sp ) \
128 do \
129 { \
130 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
131 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
132 (rp), (sp), Fp, Kp ); \
133 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100134
135#define F F1
136#define K 0x00000000
137#define Fp F5
138#define Kp 0x50A28BE6
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200139 P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
140 P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
141 P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
142 P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
143 P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
144 P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
145 P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
146 P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
147 P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
148 P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
149 P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
150 P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
151 P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
152 P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
153 P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
154 P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100155#undef F
156#undef K
157#undef Fp
158#undef Kp
159
160#define F F2
161#define K 0x5A827999
162#define Fp F4
163#define Kp 0x5C4DD124
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200164 P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
165 P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
166 P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
167 P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
168 P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
169 P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
170 P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
171 P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
172 P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
173 P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
174 P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
175 P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
176 P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
177 P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
178 P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
179 P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100180#undef F
181#undef K
182#undef Fp
183#undef Kp
184
185#define F F3
186#define K 0x6ED9EBA1
187#define Fp F3
188#define Kp 0x6D703EF3
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200189 P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
190 P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
191 P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
192 P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
193 P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
194 P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
195 P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
196 P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
197 P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
198 P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
199 P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
200 P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
201 P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
202 P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
203 P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
204 P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100205#undef F
206#undef K
207#undef Fp
208#undef Kp
209
210#define F F4
211#define K 0x8F1BBCDC
212#define Fp F2
213#define Kp 0x7A6D76E9
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200214 P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
215 P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
216 P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
217 P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
218 P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
219 P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
220 P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
221 P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
222 P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
223 P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
224 P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
225 P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
226 P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
227 P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
228 P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
229 P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100230#undef F
231#undef K
232#undef Fp
233#undef Kp
234
235#define F F5
236#define K 0xA953FD4E
237#define Fp F1
238#define Kp 0x00000000
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200239 P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
240 P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
241 P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
242 P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
243 P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
244 P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
245 P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
246 P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
247 P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
248 P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
249 P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
250 P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
251 P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
252 P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
253 P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
254 P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100255#undef F
256#undef K
257#undef Fp
258#undef Kp
259
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200260 local.C = ctx->state[1] + local.C + local.Dp;
261 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
262 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
263 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
264 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
265 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100266
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200267 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200268 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100269
270 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100271}
Jaeden Amero041039f2018-02-19 15:28:08 +0000272
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100274
275/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100276 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100277 */
TRodziewicz26371e42021-06-08 16:45:41 +0200278int mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100279 const unsigned char *input,
280 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100281{
Janos Follath24eed8d2019-11-22 13:21:35 +0000282 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100283 size_t fill;
284 uint32_t left;
285
Brian White12895d12014-04-11 11:29:42 -0400286 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100287 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100288
289 left = ctx->total[0] & 0x3F;
290 fill = 64 - left;
291
292 ctx->total[0] += (uint32_t) ilen;
293 ctx->total[0] &= 0xFFFFFFFF;
294
295 if( ctx->total[0] < (uint32_t) ilen )
296 ctx->total[1]++;
297
298 if( left && ilen >= fill )
299 {
300 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100301
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100302 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100303 return( ret );
304
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100305 input += fill;
306 ilen -= fill;
307 left = 0;
308 }
309
310 while( ilen >= 64 )
311 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100312 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100313 return( ret );
314
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100315 input += 64;
316 ilen -= 64;
317 }
318
319 if( ilen > 0 )
320 {
321 memcpy( (void *) (ctx->buffer + left), input, ilen );
322 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100323
324 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100325}
326
Paul Bakker61b699e2014-01-22 13:35:29 +0100327static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100328{
329 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
333};
334
335/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100336 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100337 */
TRodziewicz26371e42021-06-08 16:45:41 +0200338int mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100339 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100340{
Janos Follath24eed8d2019-11-22 13:21:35 +0000341 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100342 uint32_t last, padn;
343 uint32_t high, low;
344 unsigned char msglen[8];
345
346 high = ( ctx->total[0] >> 29 )
347 | ( ctx->total[1] << 3 );
348 low = ( ctx->total[0] << 3 );
349
Joe Subbiani5ecac212021-06-24 13:00:03 +0100350 MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
351 MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100352
353 last = ctx->total[0] & 0x3F;
354 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
355
TRodziewicz26371e42021-06-08 16:45:41 +0200356 ret = mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100357 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100358 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100359
TRodziewicz26371e42021-06-08 16:45:41 +0200360 ret = mbedtls_ripemd160_update( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100361 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100362 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100363
Joe Subbiani5ecac212021-06-24 13:00:03 +0100364 MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
365 MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
366 MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
367 MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
368 MBEDTLS_PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100369
370 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100371}
372
Gilles Peskine342d9282018-01-23 18:21:21 +0100373#endif /* ! MBEDTLS_RIPEMD160_ALT */
374
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100375/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100376 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100377 */
TRodziewicz26371e42021-06-08 16:45:41 +0200378int mbedtls_ripemd160( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100379 size_t ilen,
380 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100381{
Janos Follath24eed8d2019-11-22 13:21:35 +0000382 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100384
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100386
TRodziewicz26371e42021-06-08 16:45:41 +0200387 if( ( ret = mbedtls_ripemd160_starts( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100388 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100389
TRodziewicz26371e42021-06-08 16:45:41 +0200390 if( ( ret = mbedtls_ripemd160_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100391 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100392
TRodziewicz26371e42021-06-08 16:45:41 +0200393 if( ( ret = mbedtls_ripemd160_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100394 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100395
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100396exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100398
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100399 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100400}
401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100403/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100404 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100407#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100408static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100409{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100410 { "" },
411 { "a" },
412 { "abc" },
413 { "message digest" },
414 { "abcdefghijklmnopqrstuvwxyz" },
415 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
416 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200417 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100418};
419
420static const size_t ripemd160_test_strlen[TESTS] =
421{
422 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100423};
424
Paul Bakker61b699e2014-01-22 13:35:29 +0100425static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100426{
427 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
428 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
429 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
430 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
431 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
432 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
433 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
434 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
435 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
436 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
437 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
438 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
439 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
440 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
441 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
442 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
443};
444
445/*
446 * Checkup routine
447 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100449{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100450 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100451 unsigned char output[20];
452
453 memset( output, 0, sizeof output );
454
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100455 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100456 {
457 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100459
TRodziewicz26371e42021-06-08 16:45:41 +0200460 ret = mbedtls_ripemd160( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100461 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100462 if( ret != 0 )
463 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100464
Paul Bakker61b699e2014-01-22 13:35:29 +0100465 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100466 {
467 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100468 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100469 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100470
471 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100473 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100474
Paul Bakker4400ecc2016-07-19 14:41:43 +0100475 if( verbose != 0 )
476 mbedtls_printf( "\n" );
477
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100478 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100479
480fail:
481 if( verbose != 0 )
482 mbedtls_printf( "failed\n" );
483
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100484 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485}
486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489#endif /* MBEDTLS_RIPEMD160_C */