blob: ba97c1f390338f65990ae0172f07c8d750aec4bf [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
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
19
20/*
21 * The RIPEMD-160 algorithm was designed by RIPE in 1996
22 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
23 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
24 */
25
Jerome Forissier79013242021-07-28 10:24:04 +020026#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020027
28#if defined(MBEDTLS_RIPEMD160_C)
29
30#include "mbedtls/ripemd160.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010031#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020032#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020033
34#include <string.h>
35
Jens Wiklander817466c2018-05-22 13:49:31 +020036#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020037
Jens Wiklander3d3b0592019-03-20 15:30:29 +010038#if !defined(MBEDTLS_RIPEMD160_ALT)
39
Jens Wiklander32b31802023-10-06 16:59:46 +020040void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +020041{
Jens Wiklander32b31802023-10-06 16:59:46 +020042 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Jens Wiklander817466c2018-05-22 13:49:31 +020043}
44
Jens Wiklander32b31802023-10-06 16:59:46 +020045void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +020046{
Jens Wiklander32b31802023-10-06 16:59:46 +020047 if (ctx == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +020048 return;
Jens Wiklander32b31802023-10-06 16:59:46 +020049 }
Jens Wiklander817466c2018-05-22 13:49:31 +020050
Jens Wiklander32b31802023-10-06 16:59:46 +020051 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Jens Wiklander817466c2018-05-22 13:49:31 +020052}
53
Jens Wiklander32b31802023-10-06 16:59:46 +020054void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
55 const mbedtls_ripemd160_context *src)
Jens Wiklander817466c2018-05-22 13:49:31 +020056{
57 *dst = *src;
58}
59
60/*
61 * RIPEMD-160 context setup
62 */
Jens Wiklander32b31802023-10-06 16:59:46 +020063int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +020064{
65 ctx->total[0] = 0;
66 ctx->total[1] = 0;
67
68 ctx->state[0] = 0x67452301;
69 ctx->state[1] = 0xEFCDAB89;
70 ctx->state[2] = 0x98BADCFE;
71 ctx->state[3] = 0x10325476;
72 ctx->state[4] = 0xC3D2E1F0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010073
Jens Wiklander32b31802023-10-06 16:59:46 +020074 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +020075}
76
77#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
78/*
79 * Process one block
80 */
Jens Wiklander32b31802023-10-06 16:59:46 +020081int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
82 const unsigned char data[64])
Jens Wiklander817466c2018-05-22 13:49:31 +020083{
Jens Wiklander32b31802023-10-06 16:59:46 +020084 struct {
Jerome Forissier79013242021-07-28 10:24:04 +020085 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
86 } local;
Jens Wiklander817466c2018-05-22 13:49:31 +020087
Jens Wiklander32b31802023-10-06 16:59:46 +020088 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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200104
Jerome Forissier79013242021-07-28 10:24:04 +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];
Jens Wiklander817466c2018-05-22 13:49:31 +0200110
Jens Wiklander32b31802023-10-06 16:59:46 +0200111#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)))
Jens Wiklander817466c2018-05-22 13:49:31 +0200116
Jens Wiklander32b31802023-10-06 16:59:46 +0200117#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200118
Jens Wiklander32b31802023-10-06 16:59:46 +0200119#define P(a, b, c, d, e, r, s, f, k) \
Jerome Forissier79013242021-07-28 10:24:04 +0200120 do \
121 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200122 (a) += f((b), (c), (d)) + local.X[r] + (k); \
123 (a) = S((a), (s)) + (e); \
124 (c) = S((c), 10); \
125 } while (0)
Jens Wiklander817466c2018-05-22 13:49:31 +0200126
Jens Wiklander32b31802023-10-06 16:59:46 +0200127#define P2(a, b, c, d, e, r, s, rp, sp) \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200128 do \
129 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200130 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)
Jens Wiklander817466c2018-05-22 13:49:31 +0200134
135#define F F1
136#define K 0x00000000
137#define Fp F5
138#define Kp 0x50A28BE6
Jens Wiklander32b31802023-10-06 16:59:46 +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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200155#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
Jens Wiklander32b31802023-10-06 16:59:46 +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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200180#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
Jens Wiklander32b31802023-10-06 16:59:46 +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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200205#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
Jens Wiklander32b31802023-10-06 16:59:46 +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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200230#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
Jens Wiklander32b31802023-10-06 16:59:46 +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);
Jens Wiklander817466c2018-05-22 13:49:31 +0200255#undef F
256#undef K
257#undef Fp
258#undef Kp
259
Jerome Forissier79013242021-07-28 10:24:04 +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;
266
267 /* Zeroise variables to clear sensitive data from memory. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200268 mbedtls_platform_zeroize(&local, sizeof(local));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100269
Jens Wiklander32b31802023-10-06 16:59:46 +0200270 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200271}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100272
Jens Wiklander817466c2018-05-22 13:49:31 +0200273#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
274
275/*
276 * RIPEMD-160 process buffer
277 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200278int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
279 const unsigned char *input,
280 size_t ilen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200281{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200282 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200283 size_t fill;
284 uint32_t left;
285
Jens Wiklander32b31802023-10-06 16:59:46 +0200286 if (ilen == 0) {
287 return 0;
288 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200289
290 left = ctx->total[0] & 0x3F;
291 fill = 64 - left;
292
293 ctx->total[0] += (uint32_t) ilen;
294 ctx->total[0] &= 0xFFFFFFFF;
295
Jens Wiklander32b31802023-10-06 16:59:46 +0200296 if (ctx->total[0] < (uint32_t) ilen) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200297 ctx->total[1]++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200298 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200299
Jens Wiklander32b31802023-10-06 16:59:46 +0200300 if (left && ilen >= fill) {
301 memcpy((void *) (ctx->buffer + left), input, fill);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100302
Jens Wiklander32b31802023-10-06 16:59:46 +0200303 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
304 return ret;
305 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100306
Jens Wiklander817466c2018-05-22 13:49:31 +0200307 input += fill;
308 ilen -= fill;
309 left = 0;
310 }
311
Jens Wiklander32b31802023-10-06 16:59:46 +0200312 while (ilen >= 64) {
313 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
314 return ret;
315 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100316
Jens Wiklander817466c2018-05-22 13:49:31 +0200317 input += 64;
318 ilen -= 64;
319 }
320
Jens Wiklander32b31802023-10-06 16:59:46 +0200321 if (ilen > 0) {
322 memcpy((void *) (ctx->buffer + left), input, ilen);
Jens Wiklander817466c2018-05-22 13:49:31 +0200323 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100324
Jens Wiklander32b31802023-10-06 16:59:46 +0200325 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200326}
327
328static const unsigned char ripemd160_padding[64] =
329{
Jens Wiklander32b31802023-10-06 16:59:46 +0200330 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Jens Wiklander817466c2018-05-22 13:49:31 +0200331 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
334};
335
336/*
337 * RIPEMD-160 final digest
338 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200339int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
340 unsigned char output[20])
Jens Wiklander817466c2018-05-22 13:49:31 +0200341{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200342 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200343 uint32_t last, padn;
344 uint32_t high, low;
345 unsigned char msglen[8];
346
Jens Wiklander32b31802023-10-06 16:59:46 +0200347 high = (ctx->total[0] >> 29)
348 | (ctx->total[1] << 3);
349 low = (ctx->total[0] << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200350
Jens Wiklander32b31802023-10-06 16:59:46 +0200351 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
352 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
Jens Wiklander817466c2018-05-22 13:49:31 +0200353
354 last = ctx->total[0] & 0x3F;
Jens Wiklander32b31802023-10-06 16:59:46 +0200355 padn = (last < 56) ? (56 - last) : (120 - last);
Jens Wiklander817466c2018-05-22 13:49:31 +0200356
Jens Wiklander32b31802023-10-06 16:59:46 +0200357 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
358 if (ret != 0) {
359 return ret;
360 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100361
Jens Wiklander32b31802023-10-06 16:59:46 +0200362 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
363 if (ret != 0) {
364 return ret;
365 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200366
Jens Wiklander32b31802023-10-06 16:59:46 +0200367 MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0);
368 MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4);
369 MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8);
370 MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
371 MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100372
Jens Wiklander32b31802023-10-06 16:59:46 +0200373 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200374}
375
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100376#endif /* ! MBEDTLS_RIPEMD160_ALT */
377
Jens Wiklander817466c2018-05-22 13:49:31 +0200378/*
379 * output = RIPEMD-160( input buffer )
380 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200381int mbedtls_ripemd160(const unsigned char *input,
382 size_t ilen,
383 unsigned char output[20])
Jens Wiklander817466c2018-05-22 13:49:31 +0200384{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200386 mbedtls_ripemd160_context ctx;
387
Jens Wiklander32b31802023-10-06 16:59:46 +0200388 mbedtls_ripemd160_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100389
Jens Wiklander32b31802023-10-06 16:59:46 +0200390 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 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
Jens Wiklander32b31802023-10-06 16:59:46 +0200394 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100395 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200396 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100397
Jens Wiklander32b31802023-10-06 16:59:46 +0200398 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100399 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200400 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100401
402exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200403 mbedtls_ripemd160_free(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100404
Jens Wiklander32b31802023-10-06 16:59:46 +0200405 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200406}
407
408#if defined(MBEDTLS_SELF_TEST)
409/*
410 * Test vectors from the RIPEMD-160 paper and
411 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
412 */
413#define TESTS 8
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100414static const unsigned char ripemd160_test_str[TESTS][81] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200415{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100416 { "" },
417 { "a" },
418 { "abc" },
419 { "message digest" },
420 { "abcdefghijklmnopqrstuvwxyz" },
421 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
422 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken36905f92021-04-22 14:47:51 +0200423 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100424};
425
426static const size_t ripemd160_test_strlen[TESTS] =
427{
428 0, 1, 3, 14, 26, 56, 62, 80
Jens Wiklander817466c2018-05-22 13:49:31 +0200429};
430
431static const unsigned char ripemd160_test_md[TESTS][20] =
432{
433 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
434 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
435 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
436 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
437 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
438 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
439 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
440 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
441 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
442 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
443 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
444 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
445 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
446 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
447 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
448 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
449};
450
451/*
452 * Checkup routine
453 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200454int mbedtls_ripemd160_self_test(int verbose)
Jens Wiklander817466c2018-05-22 13:49:31 +0200455{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100456 int i, ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200457 unsigned char output[20];
458
Jens Wiklander32b31802023-10-06 16:59:46 +0200459 memset(output, 0, sizeof(output));
Jens Wiklander817466c2018-05-22 13:49:31 +0200460
Jens Wiklander32b31802023-10-06 16:59:46 +0200461 for (i = 0; i < TESTS; i++) {
462 if (verbose != 0) {
463 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
464 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200465
Jens Wiklander32b31802023-10-06 16:59:46 +0200466 ret = mbedtls_ripemd160(ripemd160_test_str[i],
467 ripemd160_test_strlen[i], output);
468 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100469 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200470 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200471
Jens Wiklander32b31802023-10-06 16:59:46 +0200472 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100473 ret = 1;
474 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200475 }
476
Jens Wiklander32b31802023-10-06 16:59:46 +0200477 if (verbose != 0) {
478 mbedtls_printf("passed\n");
479 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200480 }
481
Jens Wiklander32b31802023-10-06 16:59:46 +0200482 if (verbose != 0) {
483 mbedtls_printf("\n");
484 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200485
Jens Wiklander32b31802023-10-06 16:59:46 +0200486 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100487
488fail:
Jens Wiklander32b31802023-10-06 16:59:46 +0200489 if (verbose != 0) {
490 mbedtls_printf("failed\n");
491 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100492
Jens Wiklander32b31802023-10-06 16:59:46 +0200493 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200494}
495
496#endif /* MBEDTLS_SELF_TEST */
497
498#endif /* MBEDTLS_RIPEMD160_C */