blob: 721db1efe486f07b11d2f0a98cfeb62e4af329a9 [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
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010047 */
48
49/*
50 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010052 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
53 */
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000056#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020059#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010060
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010062
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000063#include "mbedtls/ripemd160.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050064#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010065
Rich Evans00ab4702015-02-06 13:43:58 +000066#include <string.h>
67
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if defined(MBEDTLS_SELF_TEST)
69#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000070#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010071#else
Rich Evans00ab4702015-02-06 13:43:58 +000072#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#define mbedtls_printf printf
74#endif /* MBEDTLS_PLATFORM_C */
75#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010076
Gilles Peskine342d9282018-01-23 18:21:21 +010077#if !defined(MBEDTLS_RIPEMD160_ALT)
78
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010079/*
80 * 32-bit integer manipulation macros (little endian)
81 */
82#ifndef GET_UINT32_LE
83#define GET_UINT32_LE(n,b,i) \
84{ \
85 (n) = ( (uint32_t) (b)[(i) ] ) \
86 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
87 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
88 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
89}
90#endif
91
92#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000093#define PUT_UINT32_LE(n,b,i) \
94{ \
95 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
96 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
97 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
98 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010099}
100#endif
101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200103{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200105}
106
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200107void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200108{
109 if( ctx == NULL )
110 return;
111
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500112 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200113}
114
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200115void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
116 const mbedtls_ripemd160_context *src )
117{
118 *dst = *src;
119}
120
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100121/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100122 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100123 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100124int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100125{
126 ctx->total[0] = 0;
127 ctx->total[1] = 0;
128
129 ctx->state[0] = 0x67452301;
130 ctx->state[1] = 0xEFCDAB89;
131 ctx->state[2] = 0x98BADCFE;
132 ctx->state[3] = 0x10325476;
133 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100134
135 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100136}
137
Jaeden Amero041039f2018-02-19 15:28:08 +0000138#if !defined(MBEDTLS_DEPRECATED_REMOVED)
139void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
140{
141 mbedtls_ripemd160_starts_ret( ctx );
142}
143#endif
144
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100146/*
147 * Process one block
148 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100149int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
150 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100151{
152 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
153
154 GET_UINT32_LE( X[ 0], data, 0 );
155 GET_UINT32_LE( X[ 1], data, 4 );
156 GET_UINT32_LE( X[ 2], data, 8 );
157 GET_UINT32_LE( X[ 3], data, 12 );
158 GET_UINT32_LE( X[ 4], data, 16 );
159 GET_UINT32_LE( X[ 5], data, 20 );
160 GET_UINT32_LE( X[ 6], data, 24 );
161 GET_UINT32_LE( X[ 7], data, 28 );
162 GET_UINT32_LE( X[ 8], data, 32 );
163 GET_UINT32_LE( X[ 9], data, 36 );
164 GET_UINT32_LE( X[10], data, 40 );
165 GET_UINT32_LE( X[11], data, 44 );
166 GET_UINT32_LE( X[12], data, 48 );
167 GET_UINT32_LE( X[13], data, 52 );
168 GET_UINT32_LE( X[14], data, 56 );
169 GET_UINT32_LE( X[15], data, 60 );
170
171 A = Ap = ctx->state[0];
172 B = Bp = ctx->state[1];
173 C = Cp = ctx->state[2];
174 D = Dp = ctx->state[3];
175 E = Ep = ctx->state[4];
176
Hanno Beckerd6028a12018-10-15 12:01:35 +0100177#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
178#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
179#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
180#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
181#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100182
Hanno Beckerd6028a12018-10-15 12:01:35 +0100183#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100184
Hanno Beckerd6028a12018-10-15 12:01:35 +0100185#define P( a, b, c, d, e, r, s, f, k ) \
186 do \
187 { \
188 (a) += f( (b), (c), (d) ) + X[r] + (k); \
189 (a) = S( (a), (s) ) + (e); \
190 (c) = S( (c), 10 ); \
191 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100192
Hanno Beckerd6028a12018-10-15 12:01:35 +0100193#define P2( a, b, c, d, e, r, s, rp, sp ) \
194 do \
195 { \
196 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
197 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
198 (rp), (sp), Fp, Kp ); \
199 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100200
201#define F F1
202#define K 0x00000000
203#define Fp F5
204#define Kp 0x50A28BE6
205 P2( A, B, C, D, E, 0, 11, 5, 8 );
206 P2( E, A, B, C, D, 1, 14, 14, 9 );
207 P2( D, E, A, B, C, 2, 15, 7, 9 );
208 P2( C, D, E, A, B, 3, 12, 0, 11 );
209 P2( B, C, D, E, A, 4, 5, 9, 13 );
210 P2( A, B, C, D, E, 5, 8, 2, 15 );
211 P2( E, A, B, C, D, 6, 7, 11, 15 );
212 P2( D, E, A, B, C, 7, 9, 4, 5 );
213 P2( C, D, E, A, B, 8, 11, 13, 7 );
214 P2( B, C, D, E, A, 9, 13, 6, 7 );
215 P2( A, B, C, D, E, 10, 14, 15, 8 );
216 P2( E, A, B, C, D, 11, 15, 8, 11 );
217 P2( D, E, A, B, C, 12, 6, 1, 14 );
218 P2( C, D, E, A, B, 13, 7, 10, 14 );
219 P2( B, C, D, E, A, 14, 9, 3, 12 );
220 P2( A, B, C, D, E, 15, 8, 12, 6 );
221#undef F
222#undef K
223#undef Fp
224#undef Kp
225
226#define F F2
227#define K 0x5A827999
228#define Fp F4
229#define Kp 0x5C4DD124
230 P2( E, A, B, C, D, 7, 7, 6, 9 );
231 P2( D, E, A, B, C, 4, 6, 11, 13 );
232 P2( C, D, E, A, B, 13, 8, 3, 15 );
233 P2( B, C, D, E, A, 1, 13, 7, 7 );
234 P2( A, B, C, D, E, 10, 11, 0, 12 );
235 P2( E, A, B, C, D, 6, 9, 13, 8 );
236 P2( D, E, A, B, C, 15, 7, 5, 9 );
237 P2( C, D, E, A, B, 3, 15, 10, 11 );
238 P2( B, C, D, E, A, 12, 7, 14, 7 );
239 P2( A, B, C, D, E, 0, 12, 15, 7 );
240 P2( E, A, B, C, D, 9, 15, 8, 12 );
241 P2( D, E, A, B, C, 5, 9, 12, 7 );
242 P2( C, D, E, A, B, 2, 11, 4, 6 );
243 P2( B, C, D, E, A, 14, 7, 9, 15 );
244 P2( A, B, C, D, E, 11, 13, 1, 13 );
245 P2( E, A, B, C, D, 8, 12, 2, 11 );
246#undef F
247#undef K
248#undef Fp
249#undef Kp
250
251#define F F3
252#define K 0x6ED9EBA1
253#define Fp F3
254#define Kp 0x6D703EF3
255 P2( D, E, A, B, C, 3, 11, 15, 9 );
256 P2( C, D, E, A, B, 10, 13, 5, 7 );
257 P2( B, C, D, E, A, 14, 6, 1, 15 );
258 P2( A, B, C, D, E, 4, 7, 3, 11 );
259 P2( E, A, B, C, D, 9, 14, 7, 8 );
260 P2( D, E, A, B, C, 15, 9, 14, 6 );
261 P2( C, D, E, A, B, 8, 13, 6, 6 );
262 P2( B, C, D, E, A, 1, 15, 9, 14 );
263 P2( A, B, C, D, E, 2, 14, 11, 12 );
264 P2( E, A, B, C, D, 7, 8, 8, 13 );
265 P2( D, E, A, B, C, 0, 13, 12, 5 );
266 P2( C, D, E, A, B, 6, 6, 2, 14 );
267 P2( B, C, D, E, A, 13, 5, 10, 13 );
268 P2( A, B, C, D, E, 11, 12, 0, 13 );
269 P2( E, A, B, C, D, 5, 7, 4, 7 );
270 P2( D, E, A, B, C, 12, 5, 13, 5 );
271#undef F
272#undef K
273#undef Fp
274#undef Kp
275
276#define F F4
277#define K 0x8F1BBCDC
278#define Fp F2
279#define Kp 0x7A6D76E9
280 P2( C, D, E, A, B, 1, 11, 8, 15 );
281 P2( B, C, D, E, A, 9, 12, 6, 5 );
282 P2( A, B, C, D, E, 11, 14, 4, 8 );
283 P2( E, A, B, C, D, 10, 15, 1, 11 );
284 P2( D, E, A, B, C, 0, 14, 3, 14 );
285 P2( C, D, E, A, B, 8, 15, 11, 14 );
286 P2( B, C, D, E, A, 12, 9, 15, 6 );
287 P2( A, B, C, D, E, 4, 8, 0, 14 );
288 P2( E, A, B, C, D, 13, 9, 5, 6 );
289 P2( D, E, A, B, C, 3, 14, 12, 9 );
290 P2( C, D, E, A, B, 7, 5, 2, 12 );
291 P2( B, C, D, E, A, 15, 6, 13, 9 );
292 P2( A, B, C, D, E, 14, 8, 9, 12 );
293 P2( E, A, B, C, D, 5, 6, 7, 5 );
294 P2( D, E, A, B, C, 6, 5, 10, 15 );
295 P2( C, D, E, A, B, 2, 12, 14, 8 );
296#undef F
297#undef K
298#undef Fp
299#undef Kp
300
301#define F F5
302#define K 0xA953FD4E
303#define Fp F1
304#define Kp 0x00000000
305 P2( B, C, D, E, A, 4, 9, 12, 8 );
306 P2( A, B, C, D, E, 0, 15, 15, 5 );
307 P2( E, A, B, C, D, 5, 5, 10, 12 );
308 P2( D, E, A, B, C, 9, 11, 4, 9 );
309 P2( C, D, E, A, B, 7, 6, 1, 12 );
310 P2( B, C, D, E, A, 12, 8, 5, 5 );
311 P2( A, B, C, D, E, 2, 13, 8, 14 );
312 P2( E, A, B, C, D, 10, 12, 7, 6 );
313 P2( D, E, A, B, C, 14, 5, 6, 8 );
314 P2( C, D, E, A, B, 1, 12, 2, 13 );
315 P2( B, C, D, E, A, 3, 13, 13, 6 );
316 P2( A, B, C, D, E, 8, 14, 14, 5 );
317 P2( E, A, B, C, D, 11, 11, 0, 15 );
318 P2( D, E, A, B, C, 6, 8, 3, 13 );
319 P2( C, D, E, A, B, 15, 5, 9, 11 );
320 P2( B, C, D, E, A, 13, 6, 11, 11 );
321#undef F
322#undef K
323#undef Fp
324#undef Kp
325
326 C = ctx->state[1] + C + Dp;
327 ctx->state[1] = ctx->state[2] + D + Ep;
328 ctx->state[2] = ctx->state[3] + E + Ap;
329 ctx->state[3] = ctx->state[4] + A + Bp;
330 ctx->state[4] = ctx->state[0] + B + Cp;
331 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100332
333 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100334}
Jaeden Amero041039f2018-02-19 15:28:08 +0000335
336#if !defined(MBEDTLS_DEPRECATED_REMOVED)
337void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
338 const unsigned char data[64] )
339{
340 mbedtls_internal_ripemd160_process( ctx, data );
341}
342#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100344
345/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100346 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100347 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100348int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100349 const unsigned char *input,
350 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100351{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100352 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100353 size_t fill;
354 uint32_t left;
355
Brian White12895d12014-04-11 11:29:42 -0400356 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100357 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100358
359 left = ctx->total[0] & 0x3F;
360 fill = 64 - left;
361
362 ctx->total[0] += (uint32_t) ilen;
363 ctx->total[0] &= 0xFFFFFFFF;
364
365 if( ctx->total[0] < (uint32_t) ilen )
366 ctx->total[1]++;
367
368 if( left && ilen >= fill )
369 {
370 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100371
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100372 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100373 return( ret );
374
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100375 input += fill;
376 ilen -= fill;
377 left = 0;
378 }
379
380 while( ilen >= 64 )
381 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100382 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100383 return( ret );
384
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100385 input += 64;
386 ilen -= 64;
387 }
388
389 if( ilen > 0 )
390 {
391 memcpy( (void *) (ctx->buffer + left), input, ilen );
392 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100393
394 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100395}
396
Jaeden Amero041039f2018-02-19 15:28:08 +0000397#if !defined(MBEDTLS_DEPRECATED_REMOVED)
398void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
399 const unsigned char *input,
400 size_t ilen )
401{
402 mbedtls_ripemd160_update_ret( ctx, input, ilen );
403}
404#endif
405
Paul Bakker61b699e2014-01-22 13:35:29 +0100406static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100407{
408 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
409 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
410 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
411 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
412};
413
414/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100415 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100416 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100417int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100418 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100419{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100420 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100421 uint32_t last, padn;
422 uint32_t high, low;
423 unsigned char msglen[8];
424
425 high = ( ctx->total[0] >> 29 )
426 | ( ctx->total[1] << 3 );
427 low = ( ctx->total[0] << 3 );
428
429 PUT_UINT32_LE( low, msglen, 0 );
430 PUT_UINT32_LE( high, msglen, 4 );
431
432 last = ctx->total[0] & 0x3F;
433 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
434
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100435 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100436 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100437 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100438
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100439 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100440 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100441 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100442
443 PUT_UINT32_LE( ctx->state[0], output, 0 );
444 PUT_UINT32_LE( ctx->state[1], output, 4 );
445 PUT_UINT32_LE( ctx->state[2], output, 8 );
446 PUT_UINT32_LE( ctx->state[3], output, 12 );
447 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100448
449 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100450}
451
Jaeden Amero041039f2018-02-19 15:28:08 +0000452#if !defined(MBEDTLS_DEPRECATED_REMOVED)
453void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
454 unsigned char output[20] )
455{
456 mbedtls_ripemd160_finish_ret( ctx, output );
457}
458#endif
459
Gilles Peskine342d9282018-01-23 18:21:21 +0100460#endif /* ! MBEDTLS_RIPEMD160_ALT */
461
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100462/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100463 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100464 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100465int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100466 size_t ilen,
467 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100468{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100469 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100473
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100474 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100475 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100476
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100477 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100478 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100479
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100480 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100481 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100482
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100483exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100485
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100486 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100487}
488
Jaeden Amero041039f2018-02-19 15:28:08 +0000489#if !defined(MBEDTLS_DEPRECATED_REMOVED)
490void mbedtls_ripemd160( const unsigned char *input,
491 size_t ilen,
492 unsigned char output[20] )
493{
494 mbedtls_ripemd160_ret( input, ilen, output );
495}
496#endif
497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100499/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100500 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100502 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100503#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100504static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100505{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100506 { "" },
507 { "a" },
508 { "abc" },
509 { "message digest" },
510 { "abcdefghijklmnopqrstuvwxyz" },
511 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
512 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
513 { "12345678901234567890123456789012345678901234567890123456789012"
514 "345678901234567890" },
515};
516
517static const size_t ripemd160_test_strlen[TESTS] =
518{
519 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100520};
521
Paul Bakker61b699e2014-01-22 13:35:29 +0100522static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100523{
524 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
525 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
526 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
527 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
528 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
529 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
530 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
531 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
532 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
533 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
534 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
535 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
536 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
537 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
538 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
539 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
540};
541
542/*
543 * Checkup routine
544 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100546{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100547 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100548 unsigned char output[20];
549
550 memset( output, 0, sizeof output );
551
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100552 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100553 {
554 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100556
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100557 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100558 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100559 if( ret != 0 )
560 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100561
Paul Bakker61b699e2014-01-22 13:35:29 +0100562 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100563 {
564 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100565 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100566 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100567
568 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100570 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100571
Paul Bakker4400ecc2016-07-19 14:41:43 +0100572 if( verbose != 0 )
573 mbedtls_printf( "\n" );
574
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100575 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100576
577fail:
578 if( verbose != 0 )
579 mbedtls_printf( "failed\n" );
580
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100581 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100582}
583
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100585
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586#endif /* MBEDTLS_RIPEMD160_C */