blob: a2e11cdf08f7b53a7e029100c6bb6a724c3e4e18 [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010018 */
19
20/*
21 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010023 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/ripemd160.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000032#include "mbedtls/error.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010037
Gilles Peskine342d9282018-01-23 18:21:21 +010038#if !defined(MBEDTLS_RIPEMD160_ALT)
39
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010040void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020041{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010042 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020043}
44
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010045void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020046{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010047 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +020048 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010049 }
Paul Bakker5b4af392014-06-26 12:09:34 +020050
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010051 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020052}
53
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010054void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
55 const mbedtls_ripemd160_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020056{
57 *dst = *src;
58}
59
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010060/*
Paul Bakker61b699e2014-01-22 13:35:29 +010061 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010062 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010063int mbedtls_ripemd160_starts_ret(mbedtls_ripemd160_context *ctx)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010064{
65 ctx->total[0] = 0;
66 ctx->total[1] = 0;
67
68 ctx->state[0] = 0x67452301;
69 ctx->state[1] = 0xEFCDAB89;
70 ctx->state[2] = 0x98BADCFE;
71 ctx->state[3] = 0x10325476;
72 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +010073
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010074 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010075}
76
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020077#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010078void mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020079{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010080 mbedtls_ripemd160_starts_ret(ctx);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020081}
82#endif
83
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010085/*
86 * Process one block
87 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010088int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
89 const unsigned char data[64])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010090{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010091 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020092 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
93 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010094
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010095 local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0);
96 local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4);
97 local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8);
98 local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12);
99 local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16);
100 local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20);
101 local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24);
102 local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28);
103 local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32);
104 local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36);
105 local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40);
106 local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44);
107 local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48);
108 local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52);
109 local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56);
110 local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100111
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200112 local.A = local.Ap = ctx->state[0];
113 local.B = local.Bp = ctx->state[1];
114 local.C = local.Cp = ctx->state[2];
115 local.D = local.Dp = ctx->state[3];
116 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100117
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100118#define F1(x, y, z) ((x) ^ (y) ^ (z))
119#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
120#define F3(x, y, z) (((x) | ~(y)) ^ (z))
121#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
122#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100124#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126#define P(a, b, c, d, e, r, s, f, k) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200127 do \
128 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129 (a) += f((b), (c), (d)) + local.X[r] + (k); \
130 (a) = S((a), (s)) + (e); \
131 (c) = S((c), 10); \
132 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100133
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100134#define P2(a, b, c, d, e, r, s, rp, sp) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100135 do \
136 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100137 P((a), (b), (c), (d), (e), (r), (s), F, K); \
138 P(a ## p, b ## p, c ## p, d ## p, e ## p, \
139 (rp), (sp), Fp, Kp); \
140 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100141
142#define F F1
143#define K 0x00000000
144#define Fp F5
145#define Kp 0x50A28BE6
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100146 P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8);
147 P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9);
148 P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9);
149 P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11);
150 P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13);
151 P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15);
152 P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15);
153 P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5);
154 P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7);
155 P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7);
156 P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8);
157 P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11);
158 P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14);
159 P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14);
160 P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12);
161 P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100162#undef F
163#undef K
164#undef Fp
165#undef Kp
166
167#define F F2
168#define K 0x5A827999
169#define Fp F4
170#define Kp 0x5C4DD124
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100171 P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9);
172 P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13);
173 P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15);
174 P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7);
175 P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12);
176 P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8);
177 P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9);
178 P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11);
179 P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7);
180 P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7);
181 P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12);
182 P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7);
183 P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6);
184 P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15);
185 P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13);
186 P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100187#undef F
188#undef K
189#undef Fp
190#undef Kp
191
192#define F F3
193#define K 0x6ED9EBA1
194#define Fp F3
195#define Kp 0x6D703EF3
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100196 P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9);
197 P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7);
198 P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15);
199 P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11);
200 P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8);
201 P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6);
202 P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6);
203 P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14);
204 P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12);
205 P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13);
206 P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5);
207 P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14);
208 P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13);
209 P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13);
210 P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7);
211 P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100212#undef F
213#undef K
214#undef Fp
215#undef Kp
216
217#define F F4
218#define K 0x8F1BBCDC
219#define Fp F2
220#define Kp 0x7A6D76E9
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100221 P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15);
222 P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5);
223 P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8);
224 P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11);
225 P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14);
226 P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14);
227 P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6);
228 P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14);
229 P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6);
230 P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9);
231 P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12);
232 P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9);
233 P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12);
234 P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5);
235 P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15);
236 P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100237#undef F
238#undef K
239#undef Fp
240#undef Kp
241
242#define F F5
243#define K 0xA953FD4E
244#define Fp F1
245#define Kp 0x00000000
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100246 P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8);
247 P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5);
248 P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12);
249 P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9);
250 P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12);
251 P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5);
252 P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14);
253 P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6);
254 P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8);
255 P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13);
256 P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6);
257 P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5);
258 P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15);
259 P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13);
260 P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11);
261 P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100262#undef F
263#undef K
264#undef Fp
265#undef Kp
266
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200267 local.C = ctx->state[1] + local.C + local.Dp;
268 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
269 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
270 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
271 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
272 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100273
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200274 /* Zeroise variables to clear sensitive data from memory. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100275 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100276
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100277 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100278}
Jaeden Amero041039f2018-02-19 15:28:08 +0000279
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200280#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100281void mbedtls_ripemd160_process(mbedtls_ripemd160_context *ctx,
282 const unsigned char data[64])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200283{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100284 mbedtls_internal_ripemd160_process(ctx, data);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200285}
286#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100288
289/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100290 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100291 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292int mbedtls_ripemd160_update_ret(mbedtls_ripemd160_context *ctx,
293 const unsigned char *input,
294 size_t ilen)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100295{
Janos Follath24eed8d2019-11-22 13:21:35 +0000296 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297 size_t fill;
298 uint32_t left;
299
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300 if (ilen == 0) {
301 return 0;
302 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100303
304 left = ctx->total[0] & 0x3F;
305 fill = 64 - left;
306
307 ctx->total[0] += (uint32_t) ilen;
308 ctx->total[0] &= 0xFFFFFFFF;
309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310 if (ctx->total[0] < (uint32_t) ilen) {
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100311 ctx->total[1]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100312 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314 if (left && ilen >= fill) {
315 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100316
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100317 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
318 return ret;
319 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100320
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100321 input += fill;
322 ilen -= fill;
323 left = 0;
324 }
325
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100326 while (ilen >= 64) {
327 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
328 return ret;
329 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100330
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100331 input += 64;
332 ilen -= 64;
333 }
334
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100335 if (ilen > 0) {
336 memcpy((void *) (ctx->buffer + left), input, ilen);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100337 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100338
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100339 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100340}
341
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200342#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100343void mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
344 const unsigned char *input,
345 size_t ilen)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200346{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100347 mbedtls_ripemd160_update_ret(ctx, input, ilen);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200348}
349#endif
350
Paul Bakker61b699e2014-01-22 13:35:29 +0100351static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100352{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100353 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 +0100354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
355 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
357};
358
359/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100360 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362int mbedtls_ripemd160_finish_ret(mbedtls_ripemd160_context *ctx,
363 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100364{
Janos Follath24eed8d2019-11-22 13:21:35 +0000365 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100366 uint32_t last, padn;
367 uint32_t high, low;
368 unsigned char msglen[8];
369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100370 high = (ctx->total[0] >> 29)
371 | (ctx->total[1] << 3);
372 low = (ctx->total[0] << 3);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100373
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
375 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100376
377 last = ctx->total[0] & 0x3F;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 padn = (last < 56) ? (56 - last) : (120 - last);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100379
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100380 ret = mbedtls_ripemd160_update_ret(ctx, ripemd160_padding, padn);
381 if (ret != 0) {
382 return ret;
383 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 ret = mbedtls_ripemd160_update_ret(ctx, msglen, 8);
386 if (ret != 0) {
387 return ret;
388 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0);
391 MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4);
392 MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8);
393 MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
394 MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100395
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100396 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100397}
398
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200399#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400void mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
401 unsigned char output[20])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200402{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403 mbedtls_ripemd160_finish_ret(ctx, output);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200404}
405#endif
406
Gilles Peskine342d9282018-01-23 18:21:21 +0100407#endif /* ! MBEDTLS_RIPEMD160_ALT */
408
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100409/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100410 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100411 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412int mbedtls_ripemd160_ret(const unsigned char *input,
413 size_t ilen,
414 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100415{
Janos Follath24eed8d2019-11-22 13:21:35 +0000416 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 mbedtls_ripemd160_init(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100420
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100421 if ((ret = mbedtls_ripemd160_starts_ret(&ctx)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100422 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100423 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100424
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100425 if ((ret = mbedtls_ripemd160_update_ret(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100426 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100427 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100428
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 if ((ret = mbedtls_ripemd160_finish_ret(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100430 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100432
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100433exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100434 mbedtls_ripemd160_free(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100435
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100436 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100437}
438
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200439#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100440void mbedtls_ripemd160(const unsigned char *input,
441 size_t ilen,
442 unsigned char output[20])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200443{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100444 mbedtls_ripemd160_ret(input, ilen, output);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200445}
446#endif
447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100449/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100450 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100452 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100453#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100454static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100455{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100456 { "" },
457 { "a" },
458 { "abc" },
459 { "message digest" },
460 { "abcdefghijklmnopqrstuvwxyz" },
461 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
462 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200463 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100464};
465
466static const size_t ripemd160_test_strlen[TESTS] =
467{
468 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100469};
470
Paul Bakker61b699e2014-01-22 13:35:29 +0100471static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100472{
473 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
474 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
475 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
476 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
477 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
478 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
479 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
480 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
481 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
482 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
483 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
484 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
485 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
486 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
487 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
488 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
489};
490
491/*
492 * Checkup routine
493 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100494int mbedtls_ripemd160_self_test(int verbose)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100495{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100496 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100497 unsigned char output[20];
498
Dave Rodgman18688702023-02-02 12:40:50 +0000499 memset(output, 0, sizeof(output));
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100500
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100501 for (i = 0; i < TESTS; i++) {
502 if (verbose != 0) {
503 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
504 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506 ret = mbedtls_ripemd160_ret(ripemd160_test_str[i],
507 ripemd160_test_strlen[i], output);
508 if (ret != 0) {
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100509 goto fail;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100510 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100511
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100512 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100513 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100514 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100515 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100516
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100517 if (verbose != 0) {
518 mbedtls_printf("passed\n");
519 }
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100520 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100522 if (verbose != 0) {
523 mbedtls_printf("\n");
524 }
Paul Bakker4400ecc2016-07-19 14:41:43 +0100525
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526 return 0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100527
528fail:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100529 if (verbose != 0) {
530 mbedtls_printf("failed\n");
531 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100532
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100533 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100534}
535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100537
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538#endif /* MBEDTLS_RIPEMD160_C */