blob: 49fee8579b22c4fa1b4d4c135b91b65ba5e00a2c [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 Peskine449bd832023-01-11 14:50:10 +010040void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020041{
Gilles Peskine449bd832023-01-11 14:50:10 +010042 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020043}
44
Gilles Peskine449bd832023-01-11 14:50:10 +010045void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020046{
Gilles Peskine449bd832023-01-11 14:50:10 +010047 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +020048 return;
Gilles Peskine449bd832023-01-11 14:50:10 +010049 }
Paul Bakker5b4af392014-06-26 12:09:34 +020050
Gilles Peskine449bd832023-01-11 14:50:10 +010051 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020052}
53
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +010063int mbedtls_ripemd160_starts(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 Peskine449bd832023-01-11 14:50:10 +010074 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010075}
76
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010078/*
79 * Process one block
80 */
Gilles Peskine449bd832023-01-11 14:50:10 +010081int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
82 const unsigned char data[64])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010083{
Gilles Peskine449bd832023-01-11 14:50:10 +010084 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020085 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
86 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010087
Gilles Peskine449bd832023-01-11 14:50:10 +010088 local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0);
89 local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4);
90 local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8);
91 local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12);
92 local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16);
93 local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20);
94 local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24);
95 local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28);
96 local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32);
97 local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36);
98 local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40);
99 local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44);
100 local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48);
101 local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52);
102 local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56);
103 local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100104
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200105 local.A = local.Ap = ctx->state[0];
106 local.B = local.Bp = ctx->state[1];
107 local.C = local.Cp = ctx->state[2];
108 local.D = local.Dp = ctx->state[3];
109 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111#define F1(x, y, z) ((x) ^ (y) ^ (z))
112#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
113#define F3(x, y, z) (((x) | ~(y)) ^ (z))
114#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
115#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100116
Gilles Peskine449bd832023-01-11 14:50:10 +0100117#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100118
Gilles Peskine449bd832023-01-11 14:50:10 +0100119#define P(a, b, c, d, e, r, s, f, k) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200120 do \
121 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 (a) += f((b), (c), (d)) + local.X[r] + (k); \
123 (a) = S((a), (s)) + (e); \
124 (c) = S((c), 10); \
125 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127#define P2(a, b, c, d, e, r, s, rp, sp) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100128 do \
129 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 P((a), (b), (c), (d), (e), (r), (s), F, K); \
131 P(a ## p, b ## p, c ## p, d ## p, e ## p, \
132 (rp), (sp), Fp, Kp); \
133 } while (0)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100134
135#define F F1
136#define K 0x00000000
137#define Fp F5
138#define Kp 0x50A28BE6
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8);
140 P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9);
141 P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9);
142 P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11);
143 P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13);
144 P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15);
145 P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15);
146 P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5);
147 P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7);
148 P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7);
149 P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8);
150 P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11);
151 P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14);
152 P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14);
153 P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12);
154 P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100155#undef F
156#undef K
157#undef Fp
158#undef Kp
159
160#define F F2
161#define K 0x5A827999
162#define Fp F4
163#define Kp 0x5C4DD124
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9);
165 P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13);
166 P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15);
167 P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7);
168 P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12);
169 P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8);
170 P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9);
171 P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11);
172 P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7);
173 P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7);
174 P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12);
175 P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7);
176 P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6);
177 P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15);
178 P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13);
179 P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100180#undef F
181#undef K
182#undef Fp
183#undef Kp
184
185#define F F3
186#define K 0x6ED9EBA1
187#define Fp F3
188#define Kp 0x6D703EF3
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9);
190 P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7);
191 P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15);
192 P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11);
193 P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8);
194 P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6);
195 P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6);
196 P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14);
197 P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12);
198 P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13);
199 P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5);
200 P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14);
201 P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13);
202 P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13);
203 P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7);
204 P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100205#undef F
206#undef K
207#undef Fp
208#undef Kp
209
210#define F F4
211#define K 0x8F1BBCDC
212#define Fp F2
213#define Kp 0x7A6D76E9
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15);
215 P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5);
216 P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8);
217 P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11);
218 P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14);
219 P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14);
220 P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6);
221 P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14);
222 P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6);
223 P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9);
224 P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12);
225 P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9);
226 P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12);
227 P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5);
228 P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15);
229 P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100230#undef F
231#undef K
232#undef Fp
233#undef Kp
234
235#define F F5
236#define K 0xA953FD4E
237#define Fp F1
238#define Kp 0x00000000
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8);
240 P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5);
241 P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12);
242 P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9);
243 P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12);
244 P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5);
245 P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14);
246 P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6);
247 P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8);
248 P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13);
249 P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6);
250 P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5);
251 P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15);
252 P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13);
253 P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11);
254 P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100255#undef F
256#undef K
257#undef Fp
258#undef Kp
259
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200260 local.C = ctx->state[1] + local.C + local.Dp;
261 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
262 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
263 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
264 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
265 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100266
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200267 /* Zeroise variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100269
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100271}
Jaeden Amero041039f2018-02-19 15:28:08 +0000272
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100274
275/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100276 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100277 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100278int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
279 const unsigned char *input,
280 size_t ilen)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100281{
Janos Follath24eed8d2019-11-22 13:21:35 +0000282 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100283 size_t fill;
284 uint32_t left;
285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 if (ilen == 0) {
287 return 0;
288 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100289
290 left = ctx->total[0] & 0x3F;
291 fill = 64 - left;
292
293 ctx->total[0] += (uint32_t) ilen;
294 ctx->total[0] &= 0xFFFFFFFF;
295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 if (ctx->total[0] < (uint32_t) ilen) {
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100299
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 if (left && ilen >= fill) {
301 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
304 return ret;
305 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100306
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100307 input += fill;
308 ilen -= fill;
309 left = 0;
310 }
311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 while (ilen >= 64) {
313 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
314 return ret;
315 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100316
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100317 input += 64;
318 ilen -= 64;
319 }
320
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 if (ilen > 0) {
322 memcpy((void *) (ctx->buffer + left), input, ilen);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100323 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100324
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100326}
327
Paul Bakker61b699e2014-01-22 13:35:29 +0100328static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100329{
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 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 +0100331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
333 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
334};
335
336/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100337 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100338 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100339int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
340 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100341{
Janos Follath24eed8d2019-11-22 13:21:35 +0000342 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100343 uint32_t last, padn;
344 uint32_t high, low;
345 unsigned char msglen[8];
346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 high = (ctx->total[0] >> 29)
348 | (ctx->total[1] << 3);
349 low = (ctx->total[0] << 3);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100350
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
352 MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100353
354 last = ctx->total[0] & 0x3F;
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 padn = (last < 56) ? (56 - last) : (120 - last);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100356
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
358 if (ret != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100359 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
363 if (ret != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100364 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0);
368 MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4);
369 MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8);
370 MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
371 MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100372
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100373 ret = 0;
374
375exit:
376 mbedtls_ripemd160_free(ctx);
377 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100378}
379
Gilles Peskine342d9282018-01-23 18:21:21 +0100380#endif /* ! MBEDTLS_RIPEMD160_ALT */
381
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100382/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100383 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100384 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100385int mbedtls_ripemd160(const unsigned char *input,
386 size_t ilen,
387 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100388{
Janos Follath24eed8d2019-11-22 13:21:35 +0000389 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 mbedtls_ripemd160_init(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100393
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100395 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100399 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100403 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100405
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100406exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 mbedtls_ripemd160_free(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100410}
411
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100413/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100414 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100416 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100417#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100418static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100419{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100420 { "" },
421 { "a" },
422 { "abc" },
423 { "message digest" },
424 { "abcdefghijklmnopqrstuvwxyz" },
425 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
426 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200427 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100428};
429
430static const size_t ripemd160_test_strlen[TESTS] =
431{
432 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100433};
434
Paul Bakker61b699e2014-01-22 13:35:29 +0100435static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100436{
437 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
438 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
439 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
440 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
441 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
442 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
443 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
444 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
445 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
446 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
447 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
448 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
449 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
450 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
451 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
452 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
453};
454
455/*
456 * Checkup routine
457 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100458int mbedtls_ripemd160_self_test(int verbose)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100459{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100460 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100461 unsigned char output[20];
462
Dave Rodgman6dd757a2023-02-02 12:40:50 +0000463 memset(output, 0, sizeof(output));
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 for (i = 0; i < TESTS; i++) {
466 if (verbose != 0) {
467 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
468 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 ret = mbedtls_ripemd160(ripemd160_test_str[i],
471 ripemd160_test_strlen[i], output);
472 if (ret != 0) {
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100473 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100477 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100478 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100479 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 if (verbose != 0) {
482 mbedtls_printf("passed\n");
483 }
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100484 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 if (verbose != 0) {
487 mbedtls_printf("\n");
488 }
Paul Bakker4400ecc2016-07-19 14:41:43 +0100489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 return 0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100491
492fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 if (verbose != 0) {
494 mbedtls_printf("failed\n");
495 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100498}
499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502#endif /* MBEDTLS_RIPEMD160_C */