blob: aed7322cff5bb7507d3054641feac3457d5c0acb [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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020047void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020048{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020050}
51
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020053{
54 if( ctx == NULL )
55 return;
56
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050057 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020058}
59
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020060void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
61 const mbedtls_ripemd160_context *src )
62{
63 *dst = *src;
64}
65
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010066/*
Paul Bakker61b699e2014-01-22 13:35:29 +010067 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010068 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010069int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010070{
71 ctx->total[0] = 0;
72 ctx->total[1] = 0;
73
74 ctx->state[0] = 0x67452301;
75 ctx->state[1] = 0xEFCDAB89;
76 ctx->state[2] = 0x98BADCFE;
77 ctx->state[3] = 0x10325476;
78 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +010079
80 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010081}
82
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020083#if !defined(MBEDTLS_DEPRECATED_REMOVED)
84void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
85{
86 mbedtls_ripemd160_starts_ret( ctx );
87}
88#endif
89
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020090#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010091/*
92 * Process one block
93 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +010094int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
95 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010096{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020097 struct
98 {
99 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
100 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100101
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100102 local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
103 local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
104 local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
105 local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
106 local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
107 local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
108 local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
109 local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
110 local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
111 local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
112 local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
113 local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
114 local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
115 local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
116 local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
117 local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100118
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200119 local.A = local.Ap = ctx->state[0];
120 local.B = local.Bp = ctx->state[1];
121 local.C = local.Cp = ctx->state[2];
122 local.D = local.Dp = ctx->state[3];
123 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100124
Hanno Becker1eeca412018-10-15 12:01:35 +0100125#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
126#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
127#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
128#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
129#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100130
Hanno Becker1eeca412018-10-15 12:01:35 +0100131#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100132
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200133#define P( a, b, c, d, e, r, s, f, k ) \
134 do \
135 { \
136 (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
137 (a) = S( (a), (s) ) + (e); \
138 (c) = S( (c), 10 ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100139 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100140
Hanno Becker1eeca412018-10-15 12:01:35 +0100141#define P2( a, b, c, d, e, r, s, rp, sp ) \
142 do \
143 { \
144 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
145 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
146 (rp), (sp), Fp, Kp ); \
147 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100148
149#define F F1
150#define K 0x00000000
151#define Fp F5
152#define Kp 0x50A28BE6
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200153 P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
154 P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
155 P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
156 P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
157 P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
158 P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
159 P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
160 P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
161 P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
162 P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
163 P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
164 P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
165 P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
166 P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
167 P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
168 P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100169#undef F
170#undef K
171#undef Fp
172#undef Kp
173
174#define F F2
175#define K 0x5A827999
176#define Fp F4
177#define Kp 0x5C4DD124
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200178 P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
179 P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
180 P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
181 P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
182 P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
183 P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
184 P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
185 P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
186 P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
187 P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
188 P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
189 P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
190 P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
191 P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
192 P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
193 P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100194#undef F
195#undef K
196#undef Fp
197#undef Kp
198
199#define F F3
200#define K 0x6ED9EBA1
201#define Fp F3
202#define Kp 0x6D703EF3
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200203 P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
204 P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
205 P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
206 P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
207 P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
208 P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
209 P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
210 P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
211 P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
212 P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
213 P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
214 P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
215 P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
216 P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
217 P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
218 P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100219#undef F
220#undef K
221#undef Fp
222#undef Kp
223
224#define F F4
225#define K 0x8F1BBCDC
226#define Fp F2
227#define Kp 0x7A6D76E9
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200228 P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
229 P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
230 P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
231 P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
232 P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
233 P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
234 P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
235 P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
236 P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
237 P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
238 P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
239 P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
240 P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
241 P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
242 P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
243 P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100244#undef F
245#undef K
246#undef Fp
247#undef Kp
248
249#define F F5
250#define K 0xA953FD4E
251#define Fp F1
252#define Kp 0x00000000
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200253 P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
254 P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
255 P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
256 P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
257 P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
258 P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
259 P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
260 P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
261 P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
262 P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
263 P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
264 P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
265 P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
266 P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
267 P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
268 P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100269#undef F
270#undef K
271#undef Fp
272#undef Kp
273
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200274 local.C = ctx->state[1] + local.C + local.Dp;
275 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
276 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
277 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
278 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
279 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100280
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200281 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200282 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100283
284 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100285}
Jaeden Amero041039f2018-02-19 15:28:08 +0000286
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200287#if !defined(MBEDTLS_DEPRECATED_REMOVED)
288void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
289 const unsigned char data[64] )
290{
291 mbedtls_internal_ripemd160_process( ctx, data );
292}
293#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100295
296/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100297 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100298 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100299int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100300 const unsigned char *input,
301 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100302{
Janos Follath24eed8d2019-11-22 13:21:35 +0000303 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100304 size_t fill;
305 uint32_t left;
306
Brian White12895d12014-04-11 11:29:42 -0400307 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100308 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100309
310 left = ctx->total[0] & 0x3F;
311 fill = 64 - left;
312
313 ctx->total[0] += (uint32_t) ilen;
314 ctx->total[0] &= 0xFFFFFFFF;
315
316 if( ctx->total[0] < (uint32_t) ilen )
317 ctx->total[1]++;
318
319 if( left && ilen >= fill )
320 {
321 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100322
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100323 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100324 return( ret );
325
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100326 input += fill;
327 ilen -= fill;
328 left = 0;
329 }
330
331 while( ilen >= 64 )
332 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100333 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100334 return( ret );
335
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100336 input += 64;
337 ilen -= 64;
338 }
339
340 if( ilen > 0 )
341 {
342 memcpy( (void *) (ctx->buffer + left), input, ilen );
343 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100344
345 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100346}
347
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200348#if !defined(MBEDTLS_DEPRECATED_REMOVED)
349void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
350 const unsigned char *input,
351 size_t ilen )
352{
353 mbedtls_ripemd160_update_ret( ctx, input, ilen );
354}
355#endif
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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100368int mbedtls_ripemd160_finish_ret( 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
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100380 MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
381 MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100382
383 last = ctx->total[0] & 0x3F;
384 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
385
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100386 ret = mbedtls_ripemd160_update_ret( 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
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100390 ret = mbedtls_ripemd160_update_ret( 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
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100394 MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
395 MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
396 MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
397 MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
398 MBEDTLS_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
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200403#if !defined(MBEDTLS_DEPRECATED_REMOVED)
404void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
405 unsigned char output[20] )
406{
407 mbedtls_ripemd160_finish_ret( ctx, output );
408}
409#endif
410
Gilles Peskine342d9282018-01-23 18:21:21 +0100411#endif /* ! MBEDTLS_RIPEMD160_ALT */
412
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100413/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100414 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100415 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100416int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100417 size_t ilen,
418 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100419{
Janos Follath24eed8d2019-11-22 13:21:35 +0000420 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100424
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100425 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100426 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100427
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100428 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100429 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100430
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100431 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100432 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100433
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100434exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100436
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100437 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100438}
439
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200440#if !defined(MBEDTLS_DEPRECATED_REMOVED)
441void mbedtls_ripemd160( const unsigned char *input,
442 size_t ilen,
443 unsigned char output[20] )
444{
445 mbedtls_ripemd160_ret( input, ilen, output );
446}
447#endif
448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100450/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100451 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100453 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100454#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100455static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100456{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100457 { "" },
458 { "a" },
459 { "abc" },
460 { "message digest" },
461 { "abcdefghijklmnopqrstuvwxyz" },
462 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
463 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200464 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100465};
466
467static const size_t ripemd160_test_strlen[TESTS] =
468{
469 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100470};
471
Paul Bakker61b699e2014-01-22 13:35:29 +0100472static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100473{
474 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
475 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
476 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
477 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
478 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
479 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
480 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
481 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
482 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
483 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
484 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
485 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
486 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
487 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
488 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
489 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
490};
491
492/*
493 * Checkup routine
494 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100496{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100497 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100498 unsigned char output[20];
499
500 memset( output, 0, sizeof output );
501
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100502 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100503 {
504 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100506
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100507 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100508 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100509 if( ret != 0 )
510 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100511
Paul Bakker61b699e2014-01-22 13:35:29 +0100512 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100513 {
514 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100515 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100516 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100517
518 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100520 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100521
Paul Bakker4400ecc2016-07-19 14:41:43 +0100522 if( verbose != 0 )
523 mbedtls_printf( "\n" );
524
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100525 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100526
527fail:
528 if( verbose != 0 )
529 mbedtls_printf( "failed\n" );
530
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100531 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100532}
533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536#endif /* MBEDTLS_RIPEMD160_C */