blob: b4fc3cdba1fc3f4af072584d8229a565487b5413 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * RIPE MD-160 implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
Tom Van Eyckc1633172024-04-09 18:44:13 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Jens Wiklander817466c2018-05-22 13:49:31 +02006 */
7
8/*
9 * The RIPEMD-160 algorithm was designed by RIPE in 1996
10 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
11 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
12 */
13
Jerome Forissier79013242021-07-28 10:24:04 +020014#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020015
16#if defined(MBEDTLS_RIPEMD160_C)
17
18#include "mbedtls/ripemd160.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010019#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020020#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020021
22#include <string.h>
23
Jens Wiklander817466c2018-05-22 13:49:31 +020024#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020025
Jens Wiklander3d3b0592019-03-20 15:30:29 +010026#if !defined(MBEDTLS_RIPEMD160_ALT)
27
Jens Wiklander32b31802023-10-06 16:59:46 +020028void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +020029{
Jens Wiklander32b31802023-10-06 16:59:46 +020030 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Jens Wiklander817466c2018-05-22 13:49:31 +020031}
32
Jens Wiklander32b31802023-10-06 16:59:46 +020033void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +020034{
Jens Wiklander32b31802023-10-06 16:59:46 +020035 if (ctx == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +020036 return;
Jens Wiklander32b31802023-10-06 16:59:46 +020037 }
Jens Wiklander817466c2018-05-22 13:49:31 +020038
Jens Wiklander32b31802023-10-06 16:59:46 +020039 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Jens Wiklander817466c2018-05-22 13:49:31 +020040}
41
Jens Wiklander32b31802023-10-06 16:59:46 +020042void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
43 const mbedtls_ripemd160_context *src)
Jens Wiklander817466c2018-05-22 13:49:31 +020044{
45 *dst = *src;
46}
47
48/*
49 * RIPEMD-160 context setup
50 */
Jens Wiklander32b31802023-10-06 16:59:46 +020051int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +020052{
53 ctx->total[0] = 0;
54 ctx->total[1] = 0;
55
56 ctx->state[0] = 0x67452301;
57 ctx->state[1] = 0xEFCDAB89;
58 ctx->state[2] = 0x98BADCFE;
59 ctx->state[3] = 0x10325476;
60 ctx->state[4] = 0xC3D2E1F0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010061
Jens Wiklander32b31802023-10-06 16:59:46 +020062 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +020063}
64
65#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
66/*
67 * Process one block
68 */
Jens Wiklander32b31802023-10-06 16:59:46 +020069int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
70 const unsigned char data[64])
Jens Wiklander817466c2018-05-22 13:49:31 +020071{
Jens Wiklander32b31802023-10-06 16:59:46 +020072 struct {
Jerome Forissier79013242021-07-28 10:24:04 +020073 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
74 } local;
Jens Wiklander817466c2018-05-22 13:49:31 +020075
Jens Wiklander32b31802023-10-06 16:59:46 +020076 local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0);
77 local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4);
78 local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8);
79 local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12);
80 local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16);
81 local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20);
82 local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24);
83 local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28);
84 local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32);
85 local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36);
86 local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40);
87 local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44);
88 local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48);
89 local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52);
90 local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56);
91 local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60);
Jens Wiklander817466c2018-05-22 13:49:31 +020092
Jerome Forissier79013242021-07-28 10:24:04 +020093 local.A = local.Ap = ctx->state[0];
94 local.B = local.Bp = ctx->state[1];
95 local.C = local.Cp = ctx->state[2];
96 local.D = local.Dp = ctx->state[3];
97 local.E = local.Ep = ctx->state[4];
Jens Wiklander817466c2018-05-22 13:49:31 +020098
Jens Wiklander32b31802023-10-06 16:59:46 +020099#define F1(x, y, z) ((x) ^ (y) ^ (z))
100#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
101#define F3(x, y, z) (((x) | ~(y)) ^ (z))
102#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
103#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
Jens Wiklander817466c2018-05-22 13:49:31 +0200104
Jens Wiklander32b31802023-10-06 16:59:46 +0200105#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200106
Jens Wiklander32b31802023-10-06 16:59:46 +0200107#define P(a, b, c, d, e, r, s, f, k) \
Jerome Forissier79013242021-07-28 10:24:04 +0200108 do \
109 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200110 (a) += f((b), (c), (d)) + local.X[r] + (k); \
111 (a) = S((a), (s)) + (e); \
112 (c) = S((c), 10); \
113 } while (0)
Jens Wiklander817466c2018-05-22 13:49:31 +0200114
Jens Wiklander32b31802023-10-06 16:59:46 +0200115#define P2(a, b, c, d, e, r, s, rp, sp) \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200116 do \
117 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200118 P((a), (b), (c), (d), (e), (r), (s), F, K); \
119 P(a ## p, b ## p, c ## p, d ## p, e ## p, \
120 (rp), (sp), Fp, Kp); \
121 } while (0)
Jens Wiklander817466c2018-05-22 13:49:31 +0200122
123#define F F1
124#define K 0x00000000
125#define Fp F5
126#define Kp 0x50A28BE6
Jens Wiklander32b31802023-10-06 16:59:46 +0200127 P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8);
128 P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9);
129 P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9);
130 P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11);
131 P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13);
132 P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15);
133 P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15);
134 P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5);
135 P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7);
136 P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7);
137 P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8);
138 P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11);
139 P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14);
140 P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14);
141 P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12);
142 P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6);
Jens Wiklander817466c2018-05-22 13:49:31 +0200143#undef F
144#undef K
145#undef Fp
146#undef Kp
147
148#define F F2
149#define K 0x5A827999
150#define Fp F4
151#define Kp 0x5C4DD124
Jens Wiklander32b31802023-10-06 16:59:46 +0200152 P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9);
153 P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13);
154 P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15);
155 P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7);
156 P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12);
157 P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8);
158 P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9);
159 P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11);
160 P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7);
161 P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7);
162 P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12);
163 P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7);
164 P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6);
165 P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15);
166 P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13);
167 P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11);
Jens Wiklander817466c2018-05-22 13:49:31 +0200168#undef F
169#undef K
170#undef Fp
171#undef Kp
172
173#define F F3
174#define K 0x6ED9EBA1
175#define Fp F3
176#define Kp 0x6D703EF3
Jens Wiklander32b31802023-10-06 16:59:46 +0200177 P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9);
178 P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7);
179 P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15);
180 P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11);
181 P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8);
182 P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6);
183 P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6);
184 P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14);
185 P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12);
186 P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13);
187 P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5);
188 P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14);
189 P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13);
190 P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13);
191 P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7);
192 P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5);
Jens Wiklander817466c2018-05-22 13:49:31 +0200193#undef F
194#undef K
195#undef Fp
196#undef Kp
197
198#define F F4
199#define K 0x8F1BBCDC
200#define Fp F2
201#define Kp 0x7A6D76E9
Jens Wiklander32b31802023-10-06 16:59:46 +0200202 P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15);
203 P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5);
204 P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8);
205 P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11);
206 P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14);
207 P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14);
208 P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6);
209 P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14);
210 P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6);
211 P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9);
212 P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12);
213 P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9);
214 P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12);
215 P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5);
216 P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15);
217 P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8);
Jens Wiklander817466c2018-05-22 13:49:31 +0200218#undef F
219#undef K
220#undef Fp
221#undef Kp
222
223#define F F5
224#define K 0xA953FD4E
225#define Fp F1
226#define Kp 0x00000000
Jens Wiklander32b31802023-10-06 16:59:46 +0200227 P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8);
228 P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5);
229 P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12);
230 P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9);
231 P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12);
232 P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5);
233 P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14);
234 P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6);
235 P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8);
236 P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13);
237 P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6);
238 P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5);
239 P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15);
240 P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13);
241 P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11);
242 P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11);
Jens Wiklander817466c2018-05-22 13:49:31 +0200243#undef F
244#undef K
245#undef Fp
246#undef Kp
247
Jerome Forissier79013242021-07-28 10:24:04 +0200248 local.C = ctx->state[1] + local.C + local.Dp;
249 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
250 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
251 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
252 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
253 ctx->state[0] = local.C;
254
255 /* Zeroise variables to clear sensitive data from memory. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200256 mbedtls_platform_zeroize(&local, sizeof(local));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100257
Jens Wiklander32b31802023-10-06 16:59:46 +0200258 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200259}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100260
Jens Wiklander817466c2018-05-22 13:49:31 +0200261#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
262
263/*
264 * RIPEMD-160 process buffer
265 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200266int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
267 const unsigned char *input,
268 size_t ilen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200269{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200270 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200271 size_t fill;
272 uint32_t left;
273
Jens Wiklander32b31802023-10-06 16:59:46 +0200274 if (ilen == 0) {
275 return 0;
276 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200277
278 left = ctx->total[0] & 0x3F;
279 fill = 64 - left;
280
281 ctx->total[0] += (uint32_t) ilen;
282 ctx->total[0] &= 0xFFFFFFFF;
283
Jens Wiklander32b31802023-10-06 16:59:46 +0200284 if (ctx->total[0] < (uint32_t) ilen) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200285 ctx->total[1]++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200286 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200287
Jens Wiklander32b31802023-10-06 16:59:46 +0200288 if (left && ilen >= fill) {
289 memcpy((void *) (ctx->buffer + left), input, fill);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100290
Jens Wiklander32b31802023-10-06 16:59:46 +0200291 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
292 return ret;
293 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100294
Jens Wiklander817466c2018-05-22 13:49:31 +0200295 input += fill;
296 ilen -= fill;
297 left = 0;
298 }
299
Jens Wiklander32b31802023-10-06 16:59:46 +0200300 while (ilen >= 64) {
301 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
302 return ret;
303 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100304
Jens Wiklander817466c2018-05-22 13:49:31 +0200305 input += 64;
306 ilen -= 64;
307 }
308
Jens Wiklander32b31802023-10-06 16:59:46 +0200309 if (ilen > 0) {
310 memcpy((void *) (ctx->buffer + left), input, ilen);
Jens Wiklander817466c2018-05-22 13:49:31 +0200311 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100312
Jens Wiklander32b31802023-10-06 16:59:46 +0200313 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200314}
315
316static const unsigned char ripemd160_padding[64] =
317{
Jens Wiklander32b31802023-10-06 16:59:46 +0200318 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Jens Wiklander817466c2018-05-22 13:49:31 +0200319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
322};
323
324/*
325 * RIPEMD-160 final digest
326 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200327int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
328 unsigned char output[20])
Jens Wiklander817466c2018-05-22 13:49:31 +0200329{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200330 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200331 uint32_t last, padn;
332 uint32_t high, low;
333 unsigned char msglen[8];
334
Jens Wiklander32b31802023-10-06 16:59:46 +0200335 high = (ctx->total[0] >> 29)
336 | (ctx->total[1] << 3);
337 low = (ctx->total[0] << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200338
Jens Wiklander32b31802023-10-06 16:59:46 +0200339 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
340 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
Jens Wiklander817466c2018-05-22 13:49:31 +0200341
342 last = ctx->total[0] & 0x3F;
Jens Wiklander32b31802023-10-06 16:59:46 +0200343 padn = (last < 56) ? (56 - last) : (120 - last);
Jens Wiklander817466c2018-05-22 13:49:31 +0200344
Jens Wiklander32b31802023-10-06 16:59:46 +0200345 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
346 if (ret != 0) {
Tom Van Eyckc1633172024-04-09 18:44:13 +0200347 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200348 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100349
Jens Wiklander32b31802023-10-06 16:59:46 +0200350 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
351 if (ret != 0) {
Tom Van Eyckc1633172024-04-09 18:44:13 +0200352 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200353 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200354
Jens Wiklander32b31802023-10-06 16:59:46 +0200355 MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0);
356 MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4);
357 MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8);
358 MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
359 MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100360
Tom Van Eyckc1633172024-04-09 18:44:13 +0200361 ret = 0;
362
363exit:
364 mbedtls_ripemd160_free(ctx);
365 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200366}
367
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100368#endif /* ! MBEDTLS_RIPEMD160_ALT */
369
Jens Wiklander817466c2018-05-22 13:49:31 +0200370/*
371 * output = RIPEMD-160( input buffer )
372 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200373int mbedtls_ripemd160(const unsigned char *input,
374 size_t ilen,
375 unsigned char output[20])
Jens Wiklander817466c2018-05-22 13:49:31 +0200376{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200377 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200378 mbedtls_ripemd160_context ctx;
379
Jens Wiklander32b31802023-10-06 16:59:46 +0200380 mbedtls_ripemd160_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100381
Jens Wiklander32b31802023-10-06 16:59:46 +0200382 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100383 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200384 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100385
Jens Wiklander32b31802023-10-06 16:59:46 +0200386 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100387 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200388 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100389
Jens Wiklander32b31802023-10-06 16:59:46 +0200390 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100391 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200392 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100393
394exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200395 mbedtls_ripemd160_free(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100396
Jens Wiklander32b31802023-10-06 16:59:46 +0200397 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200398}
399
400#if defined(MBEDTLS_SELF_TEST)
401/*
402 * Test vectors from the RIPEMD-160 paper and
403 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
404 */
405#define TESTS 8
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100406static const unsigned char ripemd160_test_str[TESTS][81] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200407{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100408 { "" },
409 { "a" },
410 { "abc" },
411 { "message digest" },
412 { "abcdefghijklmnopqrstuvwxyz" },
413 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
414 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken36905f92021-04-22 14:47:51 +0200415 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100416};
417
418static const size_t ripemd160_test_strlen[TESTS] =
419{
420 0, 1, 3, 14, 26, 56, 62, 80
Jens Wiklander817466c2018-05-22 13:49:31 +0200421};
422
423static const unsigned char ripemd160_test_md[TESTS][20] =
424{
425 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
426 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
427 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
428 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
429 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
430 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
431 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
432 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
433 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
434 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
435 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
436 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
437 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
438 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
439 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
440 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
441};
442
443/*
444 * Checkup routine
445 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200446int mbedtls_ripemd160_self_test(int verbose)
Jens Wiklander817466c2018-05-22 13:49:31 +0200447{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100448 int i, ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200449 unsigned char output[20];
450
Jens Wiklander32b31802023-10-06 16:59:46 +0200451 memset(output, 0, sizeof(output));
Jens Wiklander817466c2018-05-22 13:49:31 +0200452
Jens Wiklander32b31802023-10-06 16:59:46 +0200453 for (i = 0; i < TESTS; i++) {
454 if (verbose != 0) {
455 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
456 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200457
Jens Wiklander32b31802023-10-06 16:59:46 +0200458 ret = mbedtls_ripemd160(ripemd160_test_str[i],
459 ripemd160_test_strlen[i], output);
460 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100461 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200462 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200463
Jens Wiklander32b31802023-10-06 16:59:46 +0200464 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100465 ret = 1;
466 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200467 }
468
Jens Wiklander32b31802023-10-06 16:59:46 +0200469 if (verbose != 0) {
470 mbedtls_printf("passed\n");
471 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200472 }
473
Jens Wiklander32b31802023-10-06 16:59:46 +0200474 if (verbose != 0) {
475 mbedtls_printf("\n");
476 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200477
Jens Wiklander32b31802023-10-06 16:59:46 +0200478 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100479
480fail:
Jens Wiklander32b31802023-10-06 16:59:46 +0200481 if (verbose != 0) {
482 mbedtls_printf("failed\n");
483 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100484
Jens Wiklander32b31802023-10-06 16:59:46 +0200485 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200486}
487
488#endif /* MBEDTLS_SELF_TEST */
489
490#endif /* MBEDTLS_RIPEMD160_C */