blob: 4511445f631f56787661f6d7efe74b0c292821c8 [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010020 */
21
22/*
23 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020024 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010025 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
26 */
27
Gilles Peskinedb09ef62020-06-03 01:43:33 +020028#include "common.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010031
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/ripemd160.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050033#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000034#include "mbedtls/error.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010035
Rich Evans00ab4702015-02-06 13:43:58 +000036#include <string.h>
37
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_SELF_TEST)
39#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010041#else
Rich Evans00ab4702015-02-06 13:43:58 +000042#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#define mbedtls_printf printf
44#endif /* MBEDTLS_PLATFORM_C */
45#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Gilles Peskine342d9282018-01-23 18:21:21 +010047#if !defined(MBEDTLS_RIPEMD160_ALT)
48
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010049/*
50 * 32-bit integer manipulation macros (little endian)
51 */
52#ifndef GET_UINT32_LE
53#define GET_UINT32_LE(n,b,i) \
54{ \
55 (n) = ( (uint32_t) (b)[(i) ] ) \
56 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
57 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
58 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
59}
60#endif
61
62#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000063#define PUT_UINT32_LE(n,b,i) \
64{ \
65 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
66 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
67 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
68 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010069}
70#endif
71
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020073{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020075}
76
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020078{
79 if( ctx == NULL )
80 return;
81
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050082 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020083}
84
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020085void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
86 const mbedtls_ripemd160_context *src )
87{
88 *dst = *src;
89}
90
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010091/*
Paul Bakker61b699e2014-01-22 13:35:29 +010092 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010093 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010094int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010095{
96 ctx->total[0] = 0;
97 ctx->total[1] = 0;
98
99 ctx->state[0] = 0x67452301;
100 ctx->state[1] = 0xEFCDAB89;
101 ctx->state[2] = 0x98BADCFE;
102 ctx->state[3] = 0x10325476;
103 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100104
105 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100106}
107
Jaeden Amero041039f2018-02-19 15:28:08 +0000108#if !defined(MBEDTLS_DEPRECATED_REMOVED)
109void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
110{
111 mbedtls_ripemd160_starts_ret( ctx );
112}
113#endif
114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100116/*
117 * Process one block
118 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100119int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
120 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100121{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200122 struct
123 {
124 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
125 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100126
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200127 GET_UINT32_LE( local.X[ 0], data, 0 );
128 GET_UINT32_LE( local.X[ 1], data, 4 );
129 GET_UINT32_LE( local.X[ 2], data, 8 );
130 GET_UINT32_LE( local.X[ 3], data, 12 );
131 GET_UINT32_LE( local.X[ 4], data, 16 );
132 GET_UINT32_LE( local.X[ 5], data, 20 );
133 GET_UINT32_LE( local.X[ 6], data, 24 );
134 GET_UINT32_LE( local.X[ 7], data, 28 );
135 GET_UINT32_LE( local.X[ 8], data, 32 );
136 GET_UINT32_LE( local.X[ 9], data, 36 );
137 GET_UINT32_LE( local.X[10], data, 40 );
138 GET_UINT32_LE( local.X[11], data, 44 );
139 GET_UINT32_LE( local.X[12], data, 48 );
140 GET_UINT32_LE( local.X[13], data, 52 );
141 GET_UINT32_LE( local.X[14], data, 56 );
142 GET_UINT32_LE( local.X[15], data, 60 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100143
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200144 local.A = local.Ap = ctx->state[0];
145 local.B = local.Bp = ctx->state[1];
146 local.C = local.Cp = ctx->state[2];
147 local.D = local.Dp = ctx->state[3];
148 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100149
Hanno Becker1eeca412018-10-15 12:01:35 +0100150#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
151#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
152#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
153#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
154#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100155
Hanno Becker1eeca412018-10-15 12:01:35 +0100156#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100157
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200158#define P( a, b, c, d, e, r, s, f, k ) \
159 do \
160 { \
161 (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
162 (a) = S( (a), (s) ) + (e); \
163 (c) = S( (c), 10 ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100164 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100165
Hanno Becker1eeca412018-10-15 12:01:35 +0100166#define P2( a, b, c, d, e, r, s, rp, sp ) \
167 do \
168 { \
169 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
170 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
171 (rp), (sp), Fp, Kp ); \
172 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100173
174#define F F1
175#define K 0x00000000
176#define Fp F5
177#define Kp 0x50A28BE6
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200178 P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
179 P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
180 P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
181 P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
182 P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
183 P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
184 P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
185 P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
186 P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
187 P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
188 P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
189 P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
190 P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
191 P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
192 P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
193 P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100194#undef F
195#undef K
196#undef Fp
197#undef Kp
198
199#define F F2
200#define K 0x5A827999
201#define Fp F4
202#define Kp 0x5C4DD124
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200203 P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
204 P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
205 P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
206 P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
207 P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
208 P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
209 P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
210 P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
211 P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
212 P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
213 P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
214 P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
215 P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
216 P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
217 P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
218 P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100219#undef F
220#undef K
221#undef Fp
222#undef Kp
223
224#define F F3
225#define K 0x6ED9EBA1
226#define Fp F3
227#define Kp 0x6D703EF3
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200228 P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
229 P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
230 P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
231 P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
232 P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
233 P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
234 P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
235 P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
236 P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
237 P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
238 P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
239 P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
240 P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
241 P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
242 P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
243 P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100244#undef F
245#undef K
246#undef Fp
247#undef Kp
248
249#define F F4
250#define K 0x8F1BBCDC
251#define Fp F2
252#define Kp 0x7A6D76E9
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200253 P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
254 P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
255 P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
256 P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
257 P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
258 P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
259 P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
260 P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
261 P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
262 P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
263 P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
264 P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
265 P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
266 P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
267 P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
268 P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100269#undef F
270#undef K
271#undef Fp
272#undef Kp
273
274#define F F5
275#define K 0xA953FD4E
276#define Fp F1
277#define Kp 0x00000000
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200278 P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
279 P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
280 P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
281 P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
282 P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
283 P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
284 P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
285 P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
286 P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
287 P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
288 P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
289 P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
290 P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
291 P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
292 P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
293 P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100294#undef F
295#undef K
296#undef Fp
297#undef Kp
298
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200299 local.C = ctx->state[1] + local.C + local.Dp;
300 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
301 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
302 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
303 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
304 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100305
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200306 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200307 mbedtls_platform_zeroize( &local, sizeof( local ) );
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200308
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100309 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100310}
Jaeden Amero041039f2018-02-19 15:28:08 +0000311
312#if !defined(MBEDTLS_DEPRECATED_REMOVED)
313void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
314 const unsigned char data[64] )
315{
316 mbedtls_internal_ripemd160_process( ctx, data );
317}
318#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100320
321/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100322 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100323 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100324int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100325 const unsigned char *input,
326 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100327{
Janos Follath24eed8d2019-11-22 13:21:35 +0000328 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100329 size_t fill;
330 uint32_t left;
331
Brian White12895d12014-04-11 11:29:42 -0400332 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100333 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100334
335 left = ctx->total[0] & 0x3F;
336 fill = 64 - left;
337
338 ctx->total[0] += (uint32_t) ilen;
339 ctx->total[0] &= 0xFFFFFFFF;
340
341 if( ctx->total[0] < (uint32_t) ilen )
342 ctx->total[1]++;
343
344 if( left && ilen >= fill )
345 {
346 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100347
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100348 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100349 return( ret );
350
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100351 input += fill;
352 ilen -= fill;
353 left = 0;
354 }
355
356 while( ilen >= 64 )
357 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100358 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100359 return( ret );
360
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361 input += 64;
362 ilen -= 64;
363 }
364
365 if( ilen > 0 )
366 {
367 memcpy( (void *) (ctx->buffer + left), input, ilen );
368 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100369
370 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100371}
372
Jaeden Amero041039f2018-02-19 15:28:08 +0000373#if !defined(MBEDTLS_DEPRECATED_REMOVED)
374void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
375 const unsigned char *input,
376 size_t ilen )
377{
378 mbedtls_ripemd160_update_ret( ctx, input, ilen );
379}
380#endif
381
Paul Bakker61b699e2014-01-22 13:35:29 +0100382static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100383{
384 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
388};
389
390/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100391 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100392 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100393int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100394 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100395{
Janos Follath24eed8d2019-11-22 13:21:35 +0000396 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100397 uint32_t last, padn;
398 uint32_t high, low;
399 unsigned char msglen[8];
400
401 high = ( ctx->total[0] >> 29 )
402 | ( ctx->total[1] << 3 );
403 low = ( ctx->total[0] << 3 );
404
405 PUT_UINT32_LE( low, msglen, 0 );
406 PUT_UINT32_LE( high, msglen, 4 );
407
408 last = ctx->total[0] & 0x3F;
409 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
410
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100411 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100412 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100413 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100414
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100415 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100416 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100417 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100418
419 PUT_UINT32_LE( ctx->state[0], output, 0 );
420 PUT_UINT32_LE( ctx->state[1], output, 4 );
421 PUT_UINT32_LE( ctx->state[2], output, 8 );
422 PUT_UINT32_LE( ctx->state[3], output, 12 );
423 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100424
425 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100426}
427
Jaeden Amero041039f2018-02-19 15:28:08 +0000428#if !defined(MBEDTLS_DEPRECATED_REMOVED)
429void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
430 unsigned char output[20] )
431{
432 mbedtls_ripemd160_finish_ret( ctx, output );
433}
434#endif
435
Gilles Peskine342d9282018-01-23 18:21:21 +0100436#endif /* ! MBEDTLS_RIPEMD160_ALT */
437
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100438/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100439 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100440 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100441int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100442 size_t ilen,
443 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100444{
Janos Follath24eed8d2019-11-22 13:21:35 +0000445 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100449
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100450 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100451 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100452
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100453 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100454 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100455
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100456 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100457 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100458
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100459exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100461
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100462 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100463}
464
Jaeden Amero041039f2018-02-19 15:28:08 +0000465#if !defined(MBEDTLS_DEPRECATED_REMOVED)
466void mbedtls_ripemd160( const unsigned char *input,
467 size_t ilen,
468 unsigned char output[20] )
469{
470 mbedtls_ripemd160_ret( input, ilen, output );
471}
472#endif
473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100476 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100478 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100479#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100480static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100481{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100482 { "" },
483 { "a" },
484 { "abc" },
485 { "message digest" },
486 { "abcdefghijklmnopqrstuvwxyz" },
487 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
488 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
489 { "12345678901234567890123456789012345678901234567890123456789012"
490 "345678901234567890" },
491};
492
493static const size_t ripemd160_test_strlen[TESTS] =
494{
495 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100496};
497
Paul Bakker61b699e2014-01-22 13:35:29 +0100498static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100499{
500 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
501 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
502 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
503 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
504 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
505 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
506 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
507 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
508 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
509 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
510 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
511 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
512 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
513 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
514 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
515 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
516};
517
518/*
519 * Checkup routine
520 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100522{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100523 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100524 unsigned char output[20];
525
526 memset( output, 0, sizeof output );
527
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100528 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100529 {
530 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200531 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100532
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100533 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100534 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100535 if( ret != 0 )
536 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100537
Paul Bakker61b699e2014-01-22 13:35:29 +0100538 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100539 {
540 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100541 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100542 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100543
544 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100546 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100547
Paul Bakker4400ecc2016-07-19 14:41:43 +0100548 if( verbose != 0 )
549 mbedtls_printf( "\n" );
550
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100551 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100552
553fail:
554 if( verbose != 0 )
555 mbedtls_printf( "failed\n" );
556
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100557 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100558}
559
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100561
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562#endif /* MBEDTLS_RIPEMD160_C */