blob: b4fc3cdba1fc3f4af072584d8229a565487b5413 [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 Peskine342d9282018-01-23 18:21:21 +010026#if !defined(MBEDTLS_RIPEMD160_ALT)
27
Gilles Peskine449bd832023-01-11 14:50:10 +010028void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020029{
Gilles Peskine449bd832023-01-11 14:50:10 +010030 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020031}
32
Gilles Peskine449bd832023-01-11 14:50:10 +010033void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020034{
Gilles Peskine449bd832023-01-11 14:50:10 +010035 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +020036 return;
Gilles Peskine449bd832023-01-11 14:50:10 +010037 }
Paul Bakker5b4af392014-06-26 12:09:34 +020038
Gilles Peskine449bd832023-01-11 14:50:10 +010039 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020040}
41
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +010051int mbedtls_ripemd160_starts(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 Peskine449bd832023-01-11 14:50:10 +010062 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010063}
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010066/*
67 * Process one block
68 */
Gilles Peskine449bd832023-01-11 14:50:10 +010069int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
70 const unsigned char data[64])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010071{
Gilles Peskine449bd832023-01-11 14:50:10 +010072 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020073 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
74 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010075
Gilles Peskine449bd832023-01-11 14:50:10 +010076 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);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010092
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020093 local.A = local.Ap = ctx->state[0];
94 local.B = local.Bp = ctx->state[1];
95 local.C = local.Cp = ctx->state[2];
96 local.D = local.Dp = ctx->state[3];
97 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010098
Gilles Peskine449bd832023-01-11 14:50:10 +010099#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)))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100104
Gilles Peskine449bd832023-01-11 14:50:10 +0100105#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100106
Gilles Peskine449bd832023-01-11 14:50:10 +0100107#define P(a, b, c, d, e, r, s, f, k) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200108 do \
109 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 (a) += f((b), (c), (d)) + local.X[r] + (k); \
111 (a) = S((a), (s)) + (e); \
112 (c) = S((c), 10); \
113 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115#define P2(a, b, c, d, e, r, s, rp, sp) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100116 do \
117 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 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)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100122
123#define F F1
124#define K 0x00000000
125#define Fp F5
126#define Kp 0x50A28BE6
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 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);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100143#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
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 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);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100168#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
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 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);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100193#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
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 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);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100218#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
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 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);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100243#undef F
244#undef K
245#undef Fp
246#undef Kp
247
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200248 local.C = ctx->state[1] + local.C + local.Dp;
249 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
250 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
251 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
252 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
253 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100254
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200255 /* Zeroise variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100257
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100259}
Jaeden Amero041039f2018-02-19 15:28:08 +0000260
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200261#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100262
263/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100264 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100265 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100266int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
267 const unsigned char *input,
268 size_t ilen)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100269{
Janos Follath24eed8d2019-11-22 13:21:35 +0000270 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100271 size_t fill;
272 uint32_t left;
273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 if (ilen == 0) {
275 return 0;
276 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100277
278 left = ctx->total[0] & 0x3F;
279 fill = 64 - left;
280
281 ctx->total[0] += (uint32_t) ilen;
282 ctx->total[0] &= 0xFFFFFFFF;
283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 if (ctx->total[0] < (uint32_t) ilen) {
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100285 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 if (left && ilen >= fill) {
289 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
292 return ret;
293 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100294
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100295 input += fill;
296 ilen -= fill;
297 left = 0;
298 }
299
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 while (ilen >= 64) {
301 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
302 return ret;
303 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100304
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100305 input += 64;
306 ilen -= 64;
307 }
308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 if (ilen > 0) {
310 memcpy((void *) (ctx->buffer + left), input, ilen);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100311 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100314}
315
Paul Bakker61b699e2014-01-22 13:35:29 +0100316static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100317{
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 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 +0100319 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/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100325 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100326 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100327int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
328 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100329{
Janos Follath24eed8d2019-11-22 13:21:35 +0000330 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100331 uint32_t last, padn;
332 uint32_t high, low;
333 unsigned char msglen[8];
334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 high = (ctx->total[0] >> 29)
336 | (ctx->total[1] << 3);
337 low = (ctx->total[0] << 3);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
340 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100341
342 last = ctx->total[0] & 0x3F;
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 padn = (last < 56) ? (56 - last) : (120 - last);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
346 if (ret != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100347 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
351 if (ret != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100352 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 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);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100360
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100361 ret = 0;
362
363exit:
364 mbedtls_ripemd160_free(ctx);
365 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100366}
367
Gilles Peskine342d9282018-01-23 18:21:21 +0100368#endif /* ! MBEDTLS_RIPEMD160_ALT */
369
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100370/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100371 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100373int mbedtls_ripemd160(const unsigned char *input,
374 size_t ilen,
375 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100376{
Janos Follath24eed8d2019-11-22 13:21:35 +0000377 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100379
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 mbedtls_ripemd160_init(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 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_update(&ctx, input, ilen)) != 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
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100391 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100393
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100394exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 mbedtls_ripemd160_free(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100398}
399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100401/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100402 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100404 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100405#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100406static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100407{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100408 { "" },
409 { "a" },
410 { "abc" },
411 { "message digest" },
412 { "abcdefghijklmnopqrstuvwxyz" },
413 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
414 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200415 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100416};
417
418static const size_t ripemd160_test_strlen[TESTS] =
419{
420 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100421};
422
Paul Bakker61b699e2014-01-22 13:35:29 +0100423static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100424{
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 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100446int mbedtls_ripemd160_self_test(int verbose)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100447{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100448 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100449 unsigned char output[20];
450
Dave Rodgman6dd757a2023-02-02 12:40:50 +0000451 memset(output, 0, sizeof(output));
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 for (i = 0; i < TESTS; i++) {
454 if (verbose != 0) {
455 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
456 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100457
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 ret = mbedtls_ripemd160(ripemd160_test_str[i],
459 ripemd160_test_strlen[i], output);
460 if (ret != 0) {
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100461 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100465 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100466 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100467 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100468
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 if (verbose != 0) {
470 mbedtls_printf("passed\n");
471 }
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100472 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 if (verbose != 0) {
475 mbedtls_printf("\n");
476 }
Paul Bakker4400ecc2016-07-19 14:41:43 +0100477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 return 0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100479
480fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 if (verbose != 0) {
482 mbedtls_printf("failed\n");
483 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100486}
487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490#endif /* MBEDTLS_RIPEMD160_C */