blob: 96b546654f02d7aec2741092850ba47f56691643 [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 Rodgman16799db2023-11-02 19:47:20 +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 Peskine449bd832023-01-11 14:50:10 +010026void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020027{
Gilles Peskine449bd832023-01-11 14:50:10 +010028 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020029}
30
Gilles Peskine449bd832023-01-11 14:50:10 +010031void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020032{
Gilles Peskine449bd832023-01-11 14:50:10 +010033 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +020034 return;
Gilles Peskine449bd832023-01-11 14:50:10 +010035 }
Paul Bakker5b4af392014-06-26 12:09:34 +020036
Gilles Peskine449bd832023-01-11 14:50:10 +010037 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020038}
39
Gilles Peskine449bd832023-01-11 14:50:10 +010040void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
41 const mbedtls_ripemd160_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020042{
43 *dst = *src;
44}
45
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010046/*
Paul Bakker61b699e2014-01-22 13:35:29 +010047 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010048 */
Gilles Peskine449bd832023-01-11 14:50:10 +010049int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010050{
51 ctx->total[0] = 0;
52 ctx->total[1] = 0;
53
54 ctx->state[0] = 0x67452301;
55 ctx->state[1] = 0xEFCDAB89;
56 ctx->state[2] = 0x98BADCFE;
57 ctx->state[3] = 0x10325476;
58 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +010059
Gilles Peskine449bd832023-01-11 14:50:10 +010060 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010061}
62
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010064/*
65 * Process one block
66 */
Gilles Peskine449bd832023-01-11 14:50:10 +010067int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
68 const unsigned char data[64])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010069{
Gilles Peskine449bd832023-01-11 14:50:10 +010070 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020071 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
72 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010073
Gilles Peskine449bd832023-01-11 14:50:10 +010074 local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0);
75 local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4);
76 local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8);
77 local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12);
78 local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16);
79 local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20);
80 local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24);
81 local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28);
82 local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32);
83 local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36);
84 local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40);
85 local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44);
86 local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48);
87 local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52);
88 local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56);
89 local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010090
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020091 local.A = local.Ap = ctx->state[0];
92 local.B = local.Bp = ctx->state[1];
93 local.C = local.Cp = ctx->state[2];
94 local.D = local.Dp = ctx->state[3];
95 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010096
Gilles Peskine449bd832023-01-11 14:50:10 +010097#define F1(x, y, z) ((x) ^ (y) ^ (z))
98#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
99#define F3(x, y, z) (((x) | ~(y)) ^ (z))
100#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
101#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100102
Gilles Peskine449bd832023-01-11 14:50:10 +0100103#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100104
Gilles Peskine449bd832023-01-11 14:50:10 +0100105#define P(a, b, c, d, e, r, s, f, k) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200106 do \
107 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 (a) += f((b), (c), (d)) + local.X[r] + (k); \
109 (a) = S((a), (s)) + (e); \
110 (c) = S((c), 10); \
111 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100112
Gilles Peskine449bd832023-01-11 14:50:10 +0100113#define P2(a, b, c, d, e, r, s, rp, sp) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100114 do \
115 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 P((a), (b), (c), (d), (e), (r), (s), F, K); \
117 P(a ## p, b ## p, c ## p, d ## p, e ## p, \
118 (rp), (sp), Fp, Kp); \
119 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100120
121#define F F1
122#define K 0x00000000
123#define Fp F5
124#define Kp 0x50A28BE6
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8);
126 P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9);
127 P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9);
128 P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11);
129 P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13);
130 P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15);
131 P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15);
132 P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5);
133 P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7);
134 P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7);
135 P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8);
136 P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11);
137 P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14);
138 P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14);
139 P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12);
140 P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100141#undef F
142#undef K
143#undef Fp
144#undef Kp
145
146#define F F2
147#define K 0x5A827999
148#define Fp F4
149#define Kp 0x5C4DD124
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9);
151 P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13);
152 P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15);
153 P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7);
154 P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12);
155 P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8);
156 P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9);
157 P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11);
158 P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7);
159 P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7);
160 P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12);
161 P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7);
162 P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6);
163 P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15);
164 P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13);
165 P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100166#undef F
167#undef K
168#undef Fp
169#undef Kp
170
171#define F F3
172#define K 0x6ED9EBA1
173#define Fp F3
174#define Kp 0x6D703EF3
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9);
176 P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7);
177 P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15);
178 P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11);
179 P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8);
180 P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6);
181 P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6);
182 P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14);
183 P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12);
184 P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13);
185 P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5);
186 P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14);
187 P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13);
188 P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13);
189 P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7);
190 P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100191#undef F
192#undef K
193#undef Fp
194#undef Kp
195
196#define F F4
197#define K 0x8F1BBCDC
198#define Fp F2
199#define Kp 0x7A6D76E9
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15);
201 P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5);
202 P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8);
203 P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11);
204 P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14);
205 P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14);
206 P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6);
207 P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14);
208 P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6);
209 P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9);
210 P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12);
211 P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9);
212 P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12);
213 P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5);
214 P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15);
215 P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100216#undef F
217#undef K
218#undef Fp
219#undef Kp
220
221#define F F5
222#define K 0xA953FD4E
223#define Fp F1
224#define Kp 0x00000000
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8);
226 P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5);
227 P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12);
228 P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9);
229 P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12);
230 P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5);
231 P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14);
232 P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6);
233 P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8);
234 P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13);
235 P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6);
236 P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5);
237 P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15);
238 P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13);
239 P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11);
240 P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100241#undef F
242#undef K
243#undef Fp
244#undef Kp
245
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200246 local.C = ctx->state[1] + local.C + local.Dp;
247 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
248 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
249 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
250 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
251 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100252
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200253 /* Zeroise variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100255
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100257}
Jaeden Amero041039f2018-02-19 15:28:08 +0000258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100260
261/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100262 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100263 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100264int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
265 const unsigned char *input,
266 size_t ilen)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100267{
Janos Follath24eed8d2019-11-22 13:21:35 +0000268 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100269 size_t fill;
270 uint32_t left;
271
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 if (ilen == 0) {
273 return 0;
274 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100275
276 left = ctx->total[0] & 0x3F;
277 fill = 64 - left;
278
279 ctx->total[0] += (uint32_t) ilen;
280 ctx->total[0] &= 0xFFFFFFFF;
281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 if (ctx->total[0] < (uint32_t) ilen) {
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100283 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 if (left && ilen >= fill) {
287 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
290 return ret;
291 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100292
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100293 input += fill;
294 ilen -= fill;
295 left = 0;
296 }
297
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 while (ilen >= 64) {
299 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
300 return ret;
301 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100302
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100303 input += 64;
304 ilen -= 64;
305 }
306
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 if (ilen > 0) {
308 memcpy((void *) (ctx->buffer + left), input, ilen);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100309 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100312}
313
Paul Bakker61b699e2014-01-22 13:35:29 +0100314static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100315{
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 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 +0100317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 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};
321
322/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100323 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100324 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100325int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
326 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100327{
Janos Follath24eed8d2019-11-22 13:21:35 +0000328 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100329 uint32_t last, padn;
330 uint32_t high, low;
331 unsigned char msglen[8];
332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 high = (ctx->total[0] >> 29)
334 | (ctx->total[1] << 3);
335 low = (ctx->total[0] << 3);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
338 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100339
340 last = ctx->total[0] & 0x3F;
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 padn = (last < 56) ? (56 - last) : (120 - last);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
344 if (ret != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100345 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
349 if (ret != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100350 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100352
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0);
354 MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4);
355 MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8);
356 MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
357 MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100358
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100359 ret = 0;
360
361exit:
362 mbedtls_ripemd160_free(ctx);
363 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364}
365
366/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100367 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100368 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100369int mbedtls_ripemd160(const unsigned char *input,
370 size_t ilen,
371 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372{
Janos Follath24eed8d2019-11-22 13:21:35 +0000373 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200374 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100375
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 mbedtls_ripemd160_init(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100379 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100383 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100387 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100389
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100390exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 mbedtls_ripemd160_free(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100394}
395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100397/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100398 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100400 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100401#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100402static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100403{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100404 { "" },
405 { "a" },
406 { "abc" },
407 { "message digest" },
408 { "abcdefghijklmnopqrstuvwxyz" },
409 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
410 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200411 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100412};
413
414static const size_t ripemd160_test_strlen[TESTS] =
415{
416 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100417};
418
Paul Bakker61b699e2014-01-22 13:35:29 +0100419static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100420{
421 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
422 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
423 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
424 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
425 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
426 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
427 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
428 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
429 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
430 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
431 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
432 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
433 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
434 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
435 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
436 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
437};
438
439/*
440 * Checkup routine
441 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442int mbedtls_ripemd160_self_test(int verbose)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100443{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100444 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100445 unsigned char output[20];
446
Dave Rodgman6dd757a2023-02-02 12:40:50 +0000447 memset(output, 0, sizeof(output));
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 for (i = 0; i < TESTS; i++) {
450 if (verbose != 0) {
451 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
452 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 ret = mbedtls_ripemd160(ripemd160_test_str[i],
455 ripemd160_test_strlen[i], output);
456 if (ret != 0) {
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100457 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100461 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100462 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100463 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 if (verbose != 0) {
466 mbedtls_printf("passed\n");
467 }
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100468 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 if (verbose != 0) {
471 mbedtls_printf("\n");
472 }
Paul Bakker4400ecc2016-07-19 14:41:43 +0100473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 return 0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100475
476fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 if (verbose != 0) {
478 mbedtls_printf("failed\n");
479 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100482}
483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486#endif /* MBEDTLS_RIPEMD160_C */