blob: 835df9528a1597cc2498429a99d820da8331dc3a [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}
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010062/*
63 * Process one block
64 */
Gilles Peskine449bd832023-01-11 14:50:10 +010065int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
66 const unsigned char data[64])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010067{
Gilles Peskine449bd832023-01-11 14:50:10 +010068 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020069 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
70 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010071
Gilles Peskine449bd832023-01-11 14:50:10 +010072 local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0);
73 local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4);
74 local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8);
75 local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12);
76 local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16);
77 local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20);
78 local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24);
79 local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28);
80 local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32);
81 local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36);
82 local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40);
83 local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44);
84 local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48);
85 local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52);
86 local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56);
87 local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010088
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020089 local.A = local.Ap = ctx->state[0];
90 local.B = local.Bp = ctx->state[1];
91 local.C = local.Cp = ctx->state[2];
92 local.D = local.Dp = ctx->state[3];
93 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010094
Gilles Peskine449bd832023-01-11 14:50:10 +010095#define F1(x, y, z) ((x) ^ (y) ^ (z))
96#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
97#define F3(x, y, z) (((x) | ~(y)) ^ (z))
98#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
99#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100100
Gilles Peskine449bd832023-01-11 14:50:10 +0100101#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100102
Gilles Peskine449bd832023-01-11 14:50:10 +0100103#define P(a, b, c, d, e, r, s, f, k) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200104 do \
105 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 (a) += f((b), (c), (d)) + local.X[r] + (k); \
107 (a) = S((a), (s)) + (e); \
108 (c) = S((c), 10); \
109 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111#define P2(a, b, c, d, e, r, s, rp, sp) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100112 do \
113 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 P((a), (b), (c), (d), (e), (r), (s), F, K); \
115 P(a ## p, b ## p, c ## p, d ## p, e ## p, \
116 (rp), (sp), Fp, Kp); \
117 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100118
119#define F F1
120#define K 0x00000000
121#define Fp F5
122#define Kp 0x50A28BE6
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8);
124 P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9);
125 P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9);
126 P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11);
127 P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13);
128 P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15);
129 P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15);
130 P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5);
131 P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7);
132 P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7);
133 P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8);
134 P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11);
135 P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14);
136 P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14);
137 P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12);
138 P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100139#undef F
140#undef K
141#undef Fp
142#undef Kp
143
144#define F F2
145#define K 0x5A827999
146#define Fp F4
147#define Kp 0x5C4DD124
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9);
149 P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13);
150 P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15);
151 P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7);
152 P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12);
153 P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8);
154 P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9);
155 P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11);
156 P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7);
157 P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7);
158 P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12);
159 P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7);
160 P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6);
161 P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15);
162 P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13);
163 P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100164#undef F
165#undef K
166#undef Fp
167#undef Kp
168
169#define F F3
170#define K 0x6ED9EBA1
171#define Fp F3
172#define Kp 0x6D703EF3
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9);
174 P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7);
175 P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15);
176 P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11);
177 P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8);
178 P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6);
179 P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6);
180 P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14);
181 P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12);
182 P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13);
183 P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5);
184 P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14);
185 P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13);
186 P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13);
187 P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7);
188 P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100189#undef F
190#undef K
191#undef Fp
192#undef Kp
193
194#define F F4
195#define K 0x8F1BBCDC
196#define Fp F2
197#define Kp 0x7A6D76E9
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15);
199 P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5);
200 P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8);
201 P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11);
202 P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14);
203 P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14);
204 P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6);
205 P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14);
206 P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6);
207 P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9);
208 P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12);
209 P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9);
210 P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12);
211 P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5);
212 P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15);
213 P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100214#undef F
215#undef K
216#undef Fp
217#undef Kp
218
219#define F F5
220#define K 0xA953FD4E
221#define Fp F1
222#define Kp 0x00000000
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8);
224 P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5);
225 P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12);
226 P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9);
227 P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12);
228 P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5);
229 P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14);
230 P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6);
231 P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8);
232 P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13);
233 P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6);
234 P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5);
235 P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15);
236 P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13);
237 P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11);
238 P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100239#undef F
240#undef K
241#undef Fp
242#undef Kp
243
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200244 local.C = ctx->state[1] + local.C + local.Dp;
245 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
246 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
247 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
248 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
249 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100250
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200251 /* Zeroise variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100255}
Jaeden Amero041039f2018-02-19 15:28:08 +0000256
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100257/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100258 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100259 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100260int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
261 const unsigned char *input,
262 size_t ilen)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100263{
Janos Follath24eed8d2019-11-22 13:21:35 +0000264 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100265 size_t fill;
266 uint32_t left;
267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 if (ilen == 0) {
269 return 0;
270 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100271
272 left = ctx->total[0] & 0x3F;
273 fill = 64 - left;
274
275 ctx->total[0] += (uint32_t) ilen;
276 ctx->total[0] &= 0xFFFFFFFF;
277
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 if (ctx->total[0] < (uint32_t) ilen) {
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100279 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 if (left && ilen >= fill) {
283 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
286 return ret;
287 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100288
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100289 input += fill;
290 ilen -= fill;
291 left = 0;
292 }
293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 while (ilen >= 64) {
295 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
296 return ret;
297 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100298
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100299 input += 64;
300 ilen -= 64;
301 }
302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 if (ilen > 0) {
304 memcpy((void *) (ctx->buffer + left), input, ilen);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100305 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100306
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100308}
309
Paul Bakker61b699e2014-01-22 13:35:29 +0100310static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100311{
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 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 +0100313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
315 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
316};
317
318/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100319 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100320 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100321int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
322 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100323{
Janos Follath24eed8d2019-11-22 13:21:35 +0000324 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100325 uint32_t last, padn;
326 uint32_t high, low;
327 unsigned char msglen[8];
328
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 high = (ctx->total[0] >> 29)
330 | (ctx->total[1] << 3);
331 low = (ctx->total[0] << 3);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
334 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100335
336 last = ctx->total[0] & 0x3F;
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 padn = (last < 56) ? (56 - last) : (120 - last);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
340 if (ret != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100341 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
345 if (ret != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100346 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0);
350 MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4);
351 MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8);
352 MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
353 MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100354
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100355 ret = 0;
356
357exit:
358 mbedtls_ripemd160_free(ctx);
359 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100360}
361
362/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100363 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100365int mbedtls_ripemd160(const unsigned char *input,
366 size_t ilen,
367 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100368{
Janos Follath24eed8d2019-11-22 13:21:35 +0000369 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 mbedtls_ripemd160_init(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100375 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 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_finish(&ctx, output)) != 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
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100386exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 mbedtls_ripemd160_free(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100388
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100390}
391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100393/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100394 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100396 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100397#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100398static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100399{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100400 { "" },
401 { "a" },
402 { "abc" },
403 { "message digest" },
404 { "abcdefghijklmnopqrstuvwxyz" },
405 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
406 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200407 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100408};
409
410static const size_t ripemd160_test_strlen[TESTS] =
411{
412 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100413};
414
Paul Bakker61b699e2014-01-22 13:35:29 +0100415static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100416{
417 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
418 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
419 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
420 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
421 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
422 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
423 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
424 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
425 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
426 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
427 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
428 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
429 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
430 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
431 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
432 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
433};
434
435/*
436 * Checkup routine
437 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438int mbedtls_ripemd160_self_test(int verbose)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100439{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100440 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100441 unsigned char output[20];
442
Dave Rodgman6dd757a2023-02-02 12:40:50 +0000443 memset(output, 0, sizeof(output));
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 for (i = 0; i < TESTS; i++) {
446 if (verbose != 0) {
447 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
448 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100449
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 ret = mbedtls_ripemd160(ripemd160_test_str[i],
451 ripemd160_test_strlen[i], output);
452 if (ret != 0) {
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100453 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100457 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100458 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100459 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100460
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 if (verbose != 0) {
462 mbedtls_printf("passed\n");
463 }
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100464 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 if (verbose != 0) {
467 mbedtls_printf("\n");
468 }
Paul Bakker4400ecc2016-07-19 14:41:43 +0100469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 return 0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100471
472fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 if (verbose != 0) {
474 mbedtls_printf("failed\n");
475 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100478}
479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482#endif /* MBEDTLS_RIPEMD160_C */