blob: 58ea2de1b9ee6954a3cc5efabea1b55f2fe5e9f5 [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020030# include "mbedtls/ripemd160.h"
31# include "mbedtls/platform_util.h"
32# include "mbedtls/error.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010033
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020034# include <string.h>
Rich Evans00ab4702015-02-06 13:43:58 +000035
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020036# if defined(MBEDTLS_SELF_TEST)
37# if defined(MBEDTLS_PLATFORM_C)
38# include "mbedtls/platform.h"
39# else
40# include <stdio.h>
41# define mbedtls_printf printf
42# endif /* MBEDTLS_PLATFORM_C */
43# endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020045# if !defined(MBEDTLS_RIPEMD160_ALT)
Gilles Peskine342d9282018-01-23 18:21:21 +010046
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010047/*
48 * 32-bit integer manipulation macros (little endian)
49 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020050# 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
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010059
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020060# ifndef PUT_UINT32_LE
61# 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); \
67 }
68# endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010069
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020070void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020071{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020072 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020073}
74
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020075void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020076{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020077 if (ctx == NULL)
Paul Bakker5b4af392014-06-26 12:09:34 +020078 return;
79
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020080 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020081}
82
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
84 const mbedtls_ripemd160_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020085{
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 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200103 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100104}
105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200106# if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100107/*
108 * Process one block
109 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200110int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
111 const unsigned char data[64])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100112{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200113 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200114 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
115 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100116
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200117 GET_UINT32_LE(local.X[0], data, 0);
118 GET_UINT32_LE(local.X[1], data, 4);
119 GET_UINT32_LE(local.X[2], data, 8);
120 GET_UINT32_LE(local.X[3], data, 12);
121 GET_UINT32_LE(local.X[4], data, 16);
122 GET_UINT32_LE(local.X[5], data, 20);
123 GET_UINT32_LE(local.X[6], data, 24);
124 GET_UINT32_LE(local.X[7], data, 28);
125 GET_UINT32_LE(local.X[8], data, 32);
126 GET_UINT32_LE(local.X[9], data, 36);
127 GET_UINT32_LE(local.X[10], data, 40);
128 GET_UINT32_LE(local.X[11], data, 44);
129 GET_UINT32_LE(local.X[12], data, 48);
130 GET_UINT32_LE(local.X[13], data, 52);
131 GET_UINT32_LE(local.X[14], data, 56);
132 GET_UINT32_LE(local.X[15], data, 60);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100133
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200134 local.A = local.Ap = ctx->state[0];
135 local.B = local.Bp = ctx->state[1];
136 local.C = local.Cp = ctx->state[2];
137 local.D = local.Dp = ctx->state[3];
138 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100139
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200140# define F1(x, y, z) ((x) ^ (y) ^ (z))
141# define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
142# define F3(x, y, z) (((x) | ~(y)) ^ (z))
143# define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
144# define F5(x, y, z) ((x) ^ ((y) | ~(z)))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100145
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200146# define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100147
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200148# define P(a, b, c, d, e, r, s, f, k) \
149 do { \
150 (a) += f((b), (c), (d)) + local.X[r] + (k); \
151 (a) = S((a), (s)) + (e); \
152 (c) = S((c), 10); \
153 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100154
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200155# define P2(a, b, c, d, e, r, s, rp, sp) \
156 do { \
157 P((a), (b), (c), (d), (e), (r), (s), F, K); \
158 P(a##p, b##p, c##p, d##p, e##p, (rp), (sp), Fp, Kp); \
159 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100160
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200161# define F F1
162# define K 0x00000000
163# define Fp F5
164# define Kp 0x50A28BE6
165 P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8);
166 P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9);
167 P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9);
168 P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11);
169 P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13);
170 P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15);
171 P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15);
172 P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5);
173 P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7);
174 P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7);
175 P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8);
176 P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11);
177 P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14);
178 P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14);
179 P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12);
180 P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6);
181# undef F
182# undef K
183# undef Fp
184# undef Kp
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100185
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200186# define F F2
187# define K 0x5A827999
188# define Fp F4
189# define Kp 0x5C4DD124
190 P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9);
191 P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13);
192 P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15);
193 P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7);
194 P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12);
195 P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8);
196 P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9);
197 P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11);
198 P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7);
199 P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7);
200 P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12);
201 P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7);
202 P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6);
203 P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15);
204 P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13);
205 P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11);
206# undef F
207# undef K
208# undef Fp
209# undef Kp
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100210
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200211# define F F3
212# define K 0x6ED9EBA1
213# define Fp F3
214# define Kp 0x6D703EF3
215 P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9);
216 P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7);
217 P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15);
218 P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11);
219 P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8);
220 P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6);
221 P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6);
222 P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14);
223 P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12);
224 P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13);
225 P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5);
226 P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14);
227 P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13);
228 P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13);
229 P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7);
230 P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5);
231# undef F
232# undef K
233# undef Fp
234# undef Kp
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100235
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200236# define F F4
237# define K 0x8F1BBCDC
238# define Fp F2
239# define Kp 0x7A6D76E9
240 P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15);
241 P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5);
242 P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8);
243 P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11);
244 P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14);
245 P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14);
246 P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6);
247 P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14);
248 P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6);
249 P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9);
250 P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12);
251 P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9);
252 P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12);
253 P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5);
254 P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15);
255 P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8);
256# undef F
257# undef K
258# undef Fp
259# undef Kp
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100260
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200261# define F F5
262# define K 0xA953FD4E
263# define Fp F1
264# define Kp 0x00000000
265 P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8);
266 P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5);
267 P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12);
268 P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9);
269 P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12);
270 P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5);
271 P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14);
272 P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6);
273 P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8);
274 P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13);
275 P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6);
276 P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5);
277 P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15);
278 P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13);
279 P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11);
280 P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11);
281# undef F
282# undef K
283# undef Fp
284# undef Kp
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100285
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200286 local.C = ctx->state[1] + local.C + local.Dp;
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200287 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
288 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
289 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
290 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
291 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100292
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200293 /* Zeroise variables to clear sensitive data from memory. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200294 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100295
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200296 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297}
Jaeden Amero041039f2018-02-19 15:28:08 +0000298
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200299# endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100300
301/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100302 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100303 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200304int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
305 const unsigned char *input,
306 size_t ilen)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100307{
Janos Follath24eed8d2019-11-22 13:21:35 +0000308 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100309 size_t fill;
310 uint32_t left;
311
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200312 if (ilen == 0)
313 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100314
315 left = ctx->total[0] & 0x3F;
316 fill = 64 - left;
317
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200318 ctx->total[0] += (uint32_t)ilen;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100319 ctx->total[0] &= 0xFFFFFFFF;
320
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200321 if (ctx->total[0] < (uint32_t)ilen)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100322 ctx->total[1]++;
323
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200324 if (left && ilen >= fill) {
325 memcpy((void *)(ctx->buffer + left), input, fill);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100326
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200327 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0)
328 return ret;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100329
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100330 input += fill;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200331 ilen -= fill;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100332 left = 0;
333 }
334
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200335 while (ilen >= 64) {
336 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0)
337 return ret;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100338
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100339 input += 64;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200340 ilen -= 64;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100341 }
342
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200343 if (ilen > 0) {
344 memcpy((void *)(ctx->buffer + left), input, ilen);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100345 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100346
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200347 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100348}
349
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200350static const unsigned char ripemd160_padding[64] = {
351 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
352 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
353 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100354};
355
356/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100357 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100358 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200359int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
360 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361{
Janos Follath24eed8d2019-11-22 13:21:35 +0000362 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100363 uint32_t last, padn;
364 uint32_t high, low;
365 unsigned char msglen[8];
366
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200367 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
368 low = (ctx->total[0] << 3);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100369
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200370 PUT_UINT32_LE(low, msglen, 0);
371 PUT_UINT32_LE(high, msglen, 4);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372
373 last = ctx->total[0] & 0x3F;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200374 padn = (last < 56) ? (56 - last) : (120 - last);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100375
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200376 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
377 if (ret != 0)
378 return ret;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100379
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200380 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
381 if (ret != 0)
382 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100383
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200384 PUT_UINT32_LE(ctx->state[0], output, 0);
385 PUT_UINT32_LE(ctx->state[1], output, 4);
386 PUT_UINT32_LE(ctx->state[2], output, 8);
387 PUT_UINT32_LE(ctx->state[3], output, 12);
388 PUT_UINT32_LE(ctx->state[4], output, 16);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100389
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200390 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100391}
392
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200393# endif /* ! MBEDTLS_RIPEMD160_ALT */
Gilles Peskine342d9282018-01-23 18:21:21 +0100394
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100395/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100396 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100397 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200398int mbedtls_ripemd160(const unsigned char *input,
399 size_t ilen,
400 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100401{
Janos Follath24eed8d2019-11-22 13:21:35 +0000402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100404
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200405 mbedtls_ripemd160_init(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100406
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200407 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100408 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100409
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200410 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100411 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100412
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200413 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100414 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100415
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100416exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200417 mbedtls_ripemd160_free(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100418
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200419 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100420}
421
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200422# if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100423/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100424 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100426 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200427# define TESTS 8
428static const unsigned char ripemd160_test_str[TESTS][81] = {
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100429 { "" },
430 { "a" },
431 { "abc" },
432 { "message digest" },
433 { "abcdefghijklmnopqrstuvwxyz" },
434 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
435 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200436 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100437};
438
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200439static const size_t ripemd160_test_strlen[TESTS] = {
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100440 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100441};
442
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200443static const unsigned char ripemd160_test_md[TESTS][20] = {
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100444 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
445 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
446 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
447 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
448 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
449 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
450 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
451 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
452 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
453 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
454 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
455 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
456 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
457 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
458 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
459 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
460};
461
462/*
463 * Checkup routine
464 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200465int mbedtls_ripemd160_self_test(int verbose)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100466{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100467 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100468 unsigned char output[20];
469
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200470 memset(output, 0, sizeof(output));
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100471
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200472 for (i = 0; i < TESTS; i++) {
473 if (verbose != 0)
474 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200476 ret = mbedtls_ripemd160(ripemd160_test_str[i], ripemd160_test_strlen[i],
477 output);
478 if (ret != 0)
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100479 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100480
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200481 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100482 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100483 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100484 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200486 if (verbose != 0)
487 mbedtls_printf("passed\n");
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100488 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100489
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200490 if (verbose != 0)
491 mbedtls_printf("\n");
Paul Bakker4400ecc2016-07-19 14:41:43 +0100492
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200493 return 0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100494
495fail:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200496 if (verbose != 0)
497 mbedtls_printf("failed\n");
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100498
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200499 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100500}
501
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200502# endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504#endif /* MBEDTLS_RIPEMD160_C */