blob: 3e8ede30510c9144e0a3ecf86a2d00bfe1ef9084 [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
Dave Rodgman7ff79652023-11-03 12:04:52 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01006 */
7
8/*
9 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020010 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010011 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
12 */
13
Gilles Peskinedb09ef62020-06-03 01:43:33 +020014#include "common.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010017
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000018#include "mbedtls/ripemd160.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050019#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000020#include "mbedtls/error.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010021
Rich Evans00ab4702015-02-06 13:43:58 +000022#include <string.h>
23
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010025
Gilles Peskine342d9282018-01-23 18:21:21 +010026#if !defined(MBEDTLS_RIPEMD160_ALT)
27
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010028void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020029{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010030 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020031}
32
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010033void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020034{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010035 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +020036 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010037 }
Paul Bakker5b4af392014-06-26 12:09:34 +020038
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010039 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020040}
41
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010042void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
43 const mbedtls_ripemd160_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020044{
45 *dst = *src;
46}
47
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010048/*
Paul Bakker61b699e2014-01-22 13:35:29 +010049 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010050 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010051int mbedtls_ripemd160_starts_ret(mbedtls_ripemd160_context *ctx)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010052{
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;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +010061
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010062 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010063}
64
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020065#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010066void mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020067{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010068 mbedtls_ripemd160_starts_ret(ctx);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020069}
70#endif
71
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010073/*
74 * Process one block
75 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010076int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
77 const unsigned char data[64])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010078{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010079 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020080 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
81 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010082
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010083 local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0);
84 local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4);
85 local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8);
86 local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12);
87 local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16);
88 local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20);
89 local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24);
90 local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28);
91 local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32);
92 local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36);
93 local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40);
94 local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44);
95 local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48);
96 local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52);
97 local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56);
98 local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010099
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200100 local.A = local.Ap = ctx->state[0];
101 local.B = local.Bp = ctx->state[1];
102 local.C = local.Cp = ctx->state[2];
103 local.D = local.Dp = ctx->state[3];
104 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100105
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100106#define F1(x, y, z) ((x) ^ (y) ^ (z))
107#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
108#define F3(x, y, z) (((x) | ~(y)) ^ (z))
109#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
110#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100111
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100112#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100113
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100114#define P(a, b, c, d, e, r, s, f, k) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200115 do \
116 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 (a) += f((b), (c), (d)) + local.X[r] + (k); \
118 (a) = S((a), (s)) + (e); \
119 (c) = S((c), 10); \
120 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100121
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100122#define P2(a, b, c, d, e, r, s, rp, sp) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100123 do \
124 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100125 P((a), (b), (c), (d), (e), (r), (s), F, K); \
126 P(a ## p, b ## p, c ## p, d ## p, e ## p, \
127 (rp), (sp), Fp, Kp); \
128 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100129
130#define F F1
131#define K 0x00000000
132#define Fp F5
133#define Kp 0x50A28BE6
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100134 P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8);
135 P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9);
136 P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9);
137 P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11);
138 P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13);
139 P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15);
140 P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15);
141 P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5);
142 P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7);
143 P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7);
144 P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8);
145 P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11);
146 P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14);
147 P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14);
148 P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12);
149 P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100150#undef F
151#undef K
152#undef Fp
153#undef Kp
154
155#define F F2
156#define K 0x5A827999
157#define Fp F4
158#define Kp 0x5C4DD124
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100159 P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9);
160 P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13);
161 P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15);
162 P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7);
163 P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12);
164 P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8);
165 P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9);
166 P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11);
167 P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7);
168 P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7);
169 P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12);
170 P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7);
171 P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6);
172 P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15);
173 P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13);
174 P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100175#undef F
176#undef K
177#undef Fp
178#undef Kp
179
180#define F F3
181#define K 0x6ED9EBA1
182#define Fp F3
183#define Kp 0x6D703EF3
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100184 P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9);
185 P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7);
186 P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15);
187 P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11);
188 P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8);
189 P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6);
190 P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6);
191 P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14);
192 P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12);
193 P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13);
194 P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5);
195 P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14);
196 P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13);
197 P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13);
198 P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7);
199 P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100200#undef F
201#undef K
202#undef Fp
203#undef Kp
204
205#define F F4
206#define K 0x8F1BBCDC
207#define Fp F2
208#define Kp 0x7A6D76E9
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209 P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15);
210 P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5);
211 P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8);
212 P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11);
213 P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14);
214 P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14);
215 P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6);
216 P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14);
217 P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6);
218 P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9);
219 P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12);
220 P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9);
221 P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12);
222 P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5);
223 P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15);
224 P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100225#undef F
226#undef K
227#undef Fp
228#undef Kp
229
230#define F F5
231#define K 0xA953FD4E
232#define Fp F1
233#define Kp 0x00000000
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8);
235 P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5);
236 P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12);
237 P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9);
238 P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12);
239 P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5);
240 P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14);
241 P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6);
242 P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8);
243 P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13);
244 P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6);
245 P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5);
246 P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15);
247 P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13);
248 P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11);
249 P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100250#undef F
251#undef K
252#undef Fp
253#undef Kp
254
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200255 local.C = ctx->state[1] + local.C + local.Dp;
256 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
257 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
258 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
259 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
260 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100261
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200262 /* Zeroise variables to clear sensitive data from memory. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100263 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100264
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100266}
Jaeden Amero041039f2018-02-19 15:28:08 +0000267
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200268#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100269void mbedtls_ripemd160_process(mbedtls_ripemd160_context *ctx,
270 const unsigned char data[64])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200271{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100272 mbedtls_internal_ripemd160_process(ctx, data);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200273}
274#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100276
277/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100278 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100279 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100280int mbedtls_ripemd160_update_ret(mbedtls_ripemd160_context *ctx,
281 const unsigned char *input,
282 size_t ilen)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100283{
Janos Follath24eed8d2019-11-22 13:21:35 +0000284 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100285 size_t fill;
286 uint32_t left;
287
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 if (ilen == 0) {
289 return 0;
290 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100291
292 left = ctx->total[0] & 0x3F;
293 fill = 64 - left;
294
295 ctx->total[0] += (uint32_t) ilen;
296 ctx->total[0] &= 0xFFFFFFFF;
297
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298 if (ctx->total[0] < (uint32_t) ilen) {
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100299 ctx->total[1]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100301
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100302 if (left && ilen >= fill) {
303 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
306 return ret;
307 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100308
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100309 input += fill;
310 ilen -= fill;
311 left = 0;
312 }
313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314 while (ilen >= 64) {
315 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
316 return ret;
317 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100318
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100319 input += 64;
320 ilen -= 64;
321 }
322
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100323 if (ilen > 0) {
324 memcpy((void *) (ctx->buffer + left), input, ilen);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100325 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100326
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100327 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100328}
329
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200330#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331void mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
332 const unsigned char *input,
333 size_t ilen)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200334{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100335 mbedtls_ripemd160_update_ret(ctx, input, ilen);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200336}
337#endif
338
Paul Bakker61b699e2014-01-22 13:35:29 +0100339static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100340{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100341 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100342 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
343 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
345};
346
347/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100348 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100349 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100350int mbedtls_ripemd160_finish_ret(mbedtls_ripemd160_context *ctx,
351 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100352{
Janos Follath24eed8d2019-11-22 13:21:35 +0000353 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100354 uint32_t last, padn;
355 uint32_t high, low;
356 unsigned char msglen[8];
357
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100358 high = (ctx->total[0] >> 29)
359 | (ctx->total[1] << 3);
360 low = (ctx->total[0] << 3);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
363 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364
365 last = ctx->total[0] & 0x3F;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366 padn = (last < 56) ? (56 - last) : (120 - last);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100367
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100368 ret = mbedtls_ripemd160_update_ret(ctx, ripemd160_padding, padn);
369 if (ret != 0) {
370 return ret;
371 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100372
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100373 ret = mbedtls_ripemd160_update_ret(ctx, msglen, 8);
374 if (ret != 0) {
375 return ret;
376 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100377
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0);
379 MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4);
380 MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8);
381 MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
382 MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100383
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100384 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100385}
386
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200387#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100388void mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
389 unsigned char output[20])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200390{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391 mbedtls_ripemd160_finish_ret(ctx, output);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200392}
393#endif
394
Gilles Peskine342d9282018-01-23 18:21:21 +0100395#endif /* ! MBEDTLS_RIPEMD160_ALT */
396
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100397/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100398 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100399 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400int mbedtls_ripemd160_ret(const unsigned char *input,
401 size_t ilen,
402 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100403{
Janos Follath24eed8d2019-11-22 13:21:35 +0000404 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100407 mbedtls_ripemd160_init(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100408
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100409 if ((ret = mbedtls_ripemd160_starts_ret(&ctx)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100410 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100411 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100412
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100413 if ((ret = mbedtls_ripemd160_update_ret(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100414 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100415 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100416
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100417 if ((ret = mbedtls_ripemd160_finish_ret(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100418 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100420
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100421exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 mbedtls_ripemd160_free(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100423
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100424 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100425}
426
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200427#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100428void mbedtls_ripemd160(const unsigned char *input,
429 size_t ilen,
430 unsigned char output[20])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200431{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100432 mbedtls_ripemd160_ret(input, ilen, output);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200433}
434#endif
435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100437/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100438 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100440 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100441#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100442static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100443{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100444 { "" },
445 { "a" },
446 { "abc" },
447 { "message digest" },
448 { "abcdefghijklmnopqrstuvwxyz" },
449 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
450 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200451 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100452};
453
454static const size_t ripemd160_test_strlen[TESTS] =
455{
456 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100457};
458
Paul Bakker61b699e2014-01-22 13:35:29 +0100459static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100460{
461 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
462 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
463 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
464 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
465 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
466 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
467 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
468 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
469 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
470 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
471 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
472 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
473 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
474 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
475 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
476 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
477};
478
479/*
480 * Checkup routine
481 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100482int mbedtls_ripemd160_self_test(int verbose)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100483{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100484 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485 unsigned char output[20];
486
Dave Rodgman18688702023-02-02 12:40:50 +0000487 memset(output, 0, sizeof(output));
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100488
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100489 for (i = 0; i < TESTS; i++) {
490 if (verbose != 0) {
491 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
492 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100493
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100494 ret = mbedtls_ripemd160_ret(ripemd160_test_str[i],
495 ripemd160_test_strlen[i], output);
496 if (ret != 0) {
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100497 goto fail;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100498 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100499
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100500 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100501 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100502 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100503 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100504
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100505 if (verbose != 0) {
506 mbedtls_printf("passed\n");
507 }
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100508 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100509
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100510 if (verbose != 0) {
511 mbedtls_printf("\n");
512 }
Paul Bakker4400ecc2016-07-19 14:41:43 +0100513
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 return 0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100515
516fail:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100517 if (verbose != 0) {
518 mbedtls_printf("failed\n");
519 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100520
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100521 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100522}
523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526#endif /* MBEDTLS_RIPEMD160_C */