blob: b4fc3cdba1fc3f4af072584d8229a565487b5413 [file] [log] [blame]
Tom Rini0344c602024-10-08 13:56:50 -06001/*
2 * RIPE MD-160 implementation
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
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
14#include "common.h"
15
16#if defined(MBEDTLS_RIPEMD160_C)
17
18#include "mbedtls/ripemd160.h"
19#include "mbedtls/platform_util.h"
20#include "mbedtls/error.h"
21
22#include <string.h>
23
24#include "mbedtls/platform.h"
25
26#if !defined(MBEDTLS_RIPEMD160_ALT)
27
28void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
29{
30 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
31}
32
33void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
34{
35 if (ctx == NULL) {
36 return;
37 }
38
39 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
40}
41
42void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
43 const mbedtls_ripemd160_context *src)
44{
45 *dst = *src;
46}
47
48/*
49 * RIPEMD-160 context setup
50 */
51int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx)
52{
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;
61
62 return 0;
63}
64
65#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
66/*
67 * Process one block
68 */
69int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
70 const unsigned char data[64])
71{
72 struct {
73 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
74 } local;
75
76 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);
92
93 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];
98
99#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)))
104
105#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
106
107#define P(a, b, c, d, e, r, s, f, k) \
108 do \
109 { \
110 (a) += f((b), (c), (d)) + local.X[r] + (k); \
111 (a) = S((a), (s)) + (e); \
112 (c) = S((c), 10); \
113 } while (0)
114
115#define P2(a, b, c, d, e, r, s, rp, sp) \
116 do \
117 { \
118 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)
122
123#define F F1
124#define K 0x00000000
125#define Fp F5
126#define Kp 0x50A28BE6
127 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);
143#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
152 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);
168#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
177 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);
193#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
202 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);
218#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
227 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);
243#undef F
244#undef K
245#undef Fp
246#undef Kp
247
248 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. */
256 mbedtls_platform_zeroize(&local, sizeof(local));
257
258 return 0;
259}
260
261#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
262
263/*
264 * RIPEMD-160 process buffer
265 */
266int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
267 const unsigned char *input,
268 size_t ilen)
269{
270 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
271 size_t fill;
272 uint32_t left;
273
274 if (ilen == 0) {
275 return 0;
276 }
277
278 left = ctx->total[0] & 0x3F;
279 fill = 64 - left;
280
281 ctx->total[0] += (uint32_t) ilen;
282 ctx->total[0] &= 0xFFFFFFFF;
283
284 if (ctx->total[0] < (uint32_t) ilen) {
285 ctx->total[1]++;
286 }
287
288 if (left && ilen >= fill) {
289 memcpy((void *) (ctx->buffer + left), input, fill);
290
291 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
292 return ret;
293 }
294
295 input += fill;
296 ilen -= fill;
297 left = 0;
298 }
299
300 while (ilen >= 64) {
301 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
302 return ret;
303 }
304
305 input += 64;
306 ilen -= 64;
307 }
308
309 if (ilen > 0) {
310 memcpy((void *) (ctx->buffer + left), input, ilen);
311 }
312
313 return 0;
314}
315
316static const unsigned char ripemd160_padding[64] =
317{
318 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
319 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 */
327int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
328 unsigned char output[20])
329{
330 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
331 uint32_t last, padn;
332 uint32_t high, low;
333 unsigned char msglen[8];
334
335 high = (ctx->total[0] >> 29)
336 | (ctx->total[1] << 3);
337 low = (ctx->total[0] << 3);
338
339 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
340 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
341
342 last = ctx->total[0] & 0x3F;
343 padn = (last < 56) ? (56 - last) : (120 - last);
344
345 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
346 if (ret != 0) {
347 goto exit;
348 }
349
350 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
351 if (ret != 0) {
352 goto exit;
353 }
354
355 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);
360
361 ret = 0;
362
363exit:
364 mbedtls_ripemd160_free(ctx);
365 return ret;
366}
367
368#endif /* ! MBEDTLS_RIPEMD160_ALT */
369
370/*
371 * output = RIPEMD-160( input buffer )
372 */
373int mbedtls_ripemd160(const unsigned char *input,
374 size_t ilen,
375 unsigned char output[20])
376{
377 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
378 mbedtls_ripemd160_context ctx;
379
380 mbedtls_ripemd160_init(&ctx);
381
382 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) {
383 goto exit;
384 }
385
386 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) {
387 goto exit;
388 }
389
390 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
391 goto exit;
392 }
393
394exit:
395 mbedtls_ripemd160_free(&ctx);
396
397 return ret;
398}
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
406static const unsigned char ripemd160_test_str[TESTS][81] =
407{
408 { "" },
409 { "a" },
410 { "abc" },
411 { "message digest" },
412 { "abcdefghijklmnopqrstuvwxyz" },
413 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
414 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
415 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
416};
417
418static const size_t ripemd160_test_strlen[TESTS] =
419{
420 0, 1, 3, 14, 26, 56, 62, 80
421};
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 */
446int mbedtls_ripemd160_self_test(int verbose)
447{
448 int i, ret = 0;
449 unsigned char output[20];
450
451 memset(output, 0, sizeof(output));
452
453 for (i = 0; i < TESTS; i++) {
454 if (verbose != 0) {
455 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
456 }
457
458 ret = mbedtls_ripemd160(ripemd160_test_str[i],
459 ripemd160_test_strlen[i], output);
460 if (ret != 0) {
461 goto fail;
462 }
463
464 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
465 ret = 1;
466 goto fail;
467 }
468
469 if (verbose != 0) {
470 mbedtls_printf("passed\n");
471 }
472 }
473
474 if (verbose != 0) {
475 mbedtls_printf("\n");
476 }
477
478 return 0;
479
480fail:
481 if (verbose != 0) {
482 mbedtls_printf("failed\n");
483 }
484
485 return ret;
486}
487
488#endif /* MBEDTLS_SELF_TEST */
489
490#endif /* MBEDTLS_RIPEMD160_C */