blob: eed664f8ce2ce2e3c08a0142d8677f919bd78bef [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
David Horstmann8b6068b2023-01-05 15:42:32 +000040void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020041{
David Horstmann8b6068b2023-01-05 15:42:32 +000042 memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020043}
44
David Horstmann8b6068b2023-01-05 15:42:32 +000045void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020046{
David Horstmann8b6068b2023-01-05 15:42:32 +000047 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +020048 return;
David Horstmann8b6068b2023-01-05 15:42:32 +000049 }
Paul Bakker5b4af392014-06-26 12:09:34 +020050
David Horstmann8b6068b2023-01-05 15:42:32 +000051 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020052}
53
David Horstmann8b6068b2023-01-05 15:42:32 +000054void 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 */
David Horstmann8b6068b2023-01-05 15:42:32 +000063int 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
David Horstmann8b6068b2023-01-05 15:42:32 +000074 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 */
David Horstmann8b6068b2023-01-05 15:42:32 +000081int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
82 const unsigned char data[64])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010083{
David Horstmann8b6068b2023-01-05 15:42:32 +000084 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
David Horstmann8b6068b2023-01-05 15:42:32 +000088 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000111#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
David Horstmann8b6068b2023-01-05 15:42:32 +0000117#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100118
David Horstmann8b6068b2023-01-05 15:42:32 +0000119#define P(a, b, c, d, e, r, s, f, k) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200120 do \
121 { \
David Horstmann8b6068b2023-01-05 15:42:32 +0000122 (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
David Horstmann8b6068b2023-01-05 15:42:32 +0000127#define P2(a, b, c, d, e, r, s, rp, sp) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100128 do \
129 { \
David Horstmann8b6068b2023-01-05 15:42:32 +0000130 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000139 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000164 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000189 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000214 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000239 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. */
David Horstmann8b6068b2023-01-05 15:42:32 +0000268 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100269
David Horstmann8b6068b2023-01-05 15:42:32 +0000270 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 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000278int 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000286 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000296 if (ctx->total[0] < (uint32_t) ilen) {
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297 ctx->total[1]++;
David Horstmann8b6068b2023-01-05 15:42:32 +0000298 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100299
David Horstmann8b6068b2023-01-05 15:42:32 +0000300 if (left && ilen >= fill) {
301 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100302
David Horstmann8b6068b2023-01-05 15:42:32 +0000303 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000312 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000321 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000325 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{
David Horstmann8b6068b2023-01-05 15:42:32 +0000330 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 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000339int 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000347 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000351 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;
David Horstmann8b6068b2023-01-05 15:42:32 +0000355 padn = (last < 56) ? (56 - last) : (120 - last);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100356
David Horstmann8b6068b2023-01-05 15:42:32 +0000357 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
358 if (ret != 0) {
359 return ret;
360 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100361
David Horstmann8b6068b2023-01-05 15:42:32 +0000362 ret = mbedtls_ripemd160_update(ctx, msglen, 8);
363 if (ret != 0) {
364 return ret;
365 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100366
David Horstmann8b6068b2023-01-05 15:42:32 +0000367 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
David Horstmann8b6068b2023-01-05 15:42:32 +0000373 return 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100374}
375
Gilles Peskine342d9282018-01-23 18:21:21 +0100376#endif /* ! MBEDTLS_RIPEMD160_ALT */
377
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100378/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100379 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100380 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000381int mbedtls_ripemd160(const unsigned char *input,
382 size_t ilen,
383 unsigned char output[20])
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100384{
Janos Follath24eed8d2019-11-22 13:21:35 +0000385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100387
David Horstmann8b6068b2023-01-05 15:42:32 +0000388 mbedtls_ripemd160_init(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100389
David Horstmann8b6068b2023-01-05 15:42:32 +0000390 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100391 goto exit;
David Horstmann8b6068b2023-01-05 15:42:32 +0000392 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100393
David Horstmann8b6068b2023-01-05 15:42:32 +0000394 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100395 goto exit;
David Horstmann8b6068b2023-01-05 15:42:32 +0000396 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100397
David Horstmann8b6068b2023-01-05 15:42:32 +0000398 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100399 goto exit;
David Horstmann8b6068b2023-01-05 15:42:32 +0000400 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100401
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100402exit:
David Horstmann8b6068b2023-01-05 15:42:32 +0000403 mbedtls_ripemd160_free(&ctx);
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100404
David Horstmann8b6068b2023-01-05 15:42:32 +0000405 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406}
407
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100409/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100410 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100412 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100413#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100414static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100415{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100416 { "" },
417 { "a" },
418 { "abc" },
419 { "message digest" },
420 { "abcdefghijklmnopqrstuvwxyz" },
421 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
422 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200423 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100424};
425
426static const size_t ripemd160_test_strlen[TESTS] =
427{
428 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100429};
430
Paul Bakker61b699e2014-01-22 13:35:29 +0100431static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100432{
433 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
434 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
435 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
436 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
437 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
438 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
439 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
440 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
441 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
442 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
443 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
444 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
445 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
446 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
447 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
448 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
449};
450
451/*
452 * Checkup routine
453 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000454int mbedtls_ripemd160_self_test(int verbose)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100455{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100456 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100457 unsigned char output[20];
458
David Horstmann8b6068b2023-01-05 15:42:32 +0000459 memset(output, 0, sizeof output);
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100460
David Horstmann8b6068b2023-01-05 15:42:32 +0000461 for (i = 0; i < TESTS; i++) {
462 if (verbose != 0) {
463 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
464 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100465
David Horstmann8b6068b2023-01-05 15:42:32 +0000466 ret = mbedtls_ripemd160(ripemd160_test_str[i],
467 ripemd160_test_strlen[i], output);
468 if (ret != 0) {
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100469 goto fail;
David Horstmann8b6068b2023-01-05 15:42:32 +0000470 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100471
David Horstmann8b6068b2023-01-05 15:42:32 +0000472 if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100473 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100474 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100475 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100476
David Horstmann8b6068b2023-01-05 15:42:32 +0000477 if (verbose != 0) {
478 mbedtls_printf("passed\n");
479 }
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100480 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100481
David Horstmann8b6068b2023-01-05 15:42:32 +0000482 if (verbose != 0) {
483 mbedtls_printf("\n");
484 }
Paul Bakker4400ecc2016-07-19 14:41:43 +0100485
David Horstmann8b6068b2023-01-05 15:42:32 +0000486 return 0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100487
488fail:
David Horstmann8b6068b2023-01-05 15:42:32 +0000489 if (verbose != 0) {
490 mbedtls_printf("failed\n");
491 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100492
David Horstmann8b6068b2023-01-05 15:42:32 +0000493 return ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100494}
495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#endif /* MBEDTLS_RIPEMD160_C */