blob: aee1123114bded52dbb1660443d90de74d2cd0ae [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-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úti4e9f7122020-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 * **********
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010045 */
46
47/*
48 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010050 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
51 */
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010060
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/ripemd160.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010062
Rich Evans00ab4702015-02-06 13:43:58 +000063#include <string.h>
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_SELF_TEST)
66#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068#else
Rich Evans00ab4702015-02-06 13:43:58 +000069#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#define mbedtls_printf printf
71#endif /* MBEDTLS_PLATFORM_C */
72#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010073
Gilles Peskine342d9282018-01-23 18:21:21 +010074#if !defined(MBEDTLS_RIPEMD160_ALT)
75
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010076/*
77 * 32-bit integer manipulation macros (little endian)
78 */
79#ifndef GET_UINT32_LE
80#define GET_UINT32_LE(n,b,i) \
81{ \
82 (n) = ( (uint32_t) (b)[(i) ] ) \
83 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
84 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
85 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
86}
87#endif
88
89#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000090#define PUT_UINT32_LE(n,b,i) \
91{ \
92 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
93 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
94 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
95 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010096}
97#endif
98
Paul Bakker34617722014-06-13 17:20:13 +020099/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +0200101 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
102}
103
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200105{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200107}
108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200110{
111 if( ctx == NULL )
112 return;
113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200115}
116
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200117void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
118 const mbedtls_ripemd160_context *src )
119{
120 *dst = *src;
121}
122
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100123/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100124 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100125 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100126int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100127{
128 ctx->total[0] = 0;
129 ctx->total[1] = 0;
130
131 ctx->state[0] = 0x67452301;
132 ctx->state[1] = 0xEFCDAB89;
133 ctx->state[2] = 0x98BADCFE;
134 ctx->state[3] = 0x10325476;
135 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100136
137 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100138}
139
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000140#if !defined(MBEDTLS_DEPRECATED_REMOVED)
141void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
142{
143 mbedtls_ripemd160_starts_ret( ctx );
144}
145#endif
146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100148/*
149 * Process one block
150 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100151int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
152 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100153{
154 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
155
156 GET_UINT32_LE( X[ 0], data, 0 );
157 GET_UINT32_LE( X[ 1], data, 4 );
158 GET_UINT32_LE( X[ 2], data, 8 );
159 GET_UINT32_LE( X[ 3], data, 12 );
160 GET_UINT32_LE( X[ 4], data, 16 );
161 GET_UINT32_LE( X[ 5], data, 20 );
162 GET_UINT32_LE( X[ 6], data, 24 );
163 GET_UINT32_LE( X[ 7], data, 28 );
164 GET_UINT32_LE( X[ 8], data, 32 );
165 GET_UINT32_LE( X[ 9], data, 36 );
166 GET_UINT32_LE( X[10], data, 40 );
167 GET_UINT32_LE( X[11], data, 44 );
168 GET_UINT32_LE( X[12], data, 48 );
169 GET_UINT32_LE( X[13], data, 52 );
170 GET_UINT32_LE( X[14], data, 56 );
171 GET_UINT32_LE( X[15], data, 60 );
172
173 A = Ap = ctx->state[0];
174 B = Bp = ctx->state[1];
175 C = Cp = ctx->state[2];
176 D = Dp = ctx->state[3];
177 E = Ep = ctx->state[4];
178
179#define F1( x, y, z ) ( x ^ y ^ z )
180#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
181#define F3( x, y, z ) ( ( x | ~y ) ^ z )
182#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
183#define F5( x, y, z ) ( x ^ ( y | ~z ) )
184
185#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
186
187#define P( a, b, c, d, e, r, s, f, k ) \
188 a += f( b, c, d ) + X[r] + k; \
189 a = S( a, s ) + e; \
190 c = S( c, 10 );
191
192#define P2( a, b, c, d, e, r, s, rp, sp ) \
193 P( a, b, c, d, e, r, s, F, K ); \
194 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
195
196#define F F1
197#define K 0x00000000
198#define Fp F5
199#define Kp 0x50A28BE6
200 P2( A, B, C, D, E, 0, 11, 5, 8 );
201 P2( E, A, B, C, D, 1, 14, 14, 9 );
202 P2( D, E, A, B, C, 2, 15, 7, 9 );
203 P2( C, D, E, A, B, 3, 12, 0, 11 );
204 P2( B, C, D, E, A, 4, 5, 9, 13 );
205 P2( A, B, C, D, E, 5, 8, 2, 15 );
206 P2( E, A, B, C, D, 6, 7, 11, 15 );
207 P2( D, E, A, B, C, 7, 9, 4, 5 );
208 P2( C, D, E, A, B, 8, 11, 13, 7 );
209 P2( B, C, D, E, A, 9, 13, 6, 7 );
210 P2( A, B, C, D, E, 10, 14, 15, 8 );
211 P2( E, A, B, C, D, 11, 15, 8, 11 );
212 P2( D, E, A, B, C, 12, 6, 1, 14 );
213 P2( C, D, E, A, B, 13, 7, 10, 14 );
214 P2( B, C, D, E, A, 14, 9, 3, 12 );
215 P2( A, B, C, D, E, 15, 8, 12, 6 );
216#undef F
217#undef K
218#undef Fp
219#undef Kp
220
221#define F F2
222#define K 0x5A827999
223#define Fp F4
224#define Kp 0x5C4DD124
225 P2( E, A, B, C, D, 7, 7, 6, 9 );
226 P2( D, E, A, B, C, 4, 6, 11, 13 );
227 P2( C, D, E, A, B, 13, 8, 3, 15 );
228 P2( B, C, D, E, A, 1, 13, 7, 7 );
229 P2( A, B, C, D, E, 10, 11, 0, 12 );
230 P2( E, A, B, C, D, 6, 9, 13, 8 );
231 P2( D, E, A, B, C, 15, 7, 5, 9 );
232 P2( C, D, E, A, B, 3, 15, 10, 11 );
233 P2( B, C, D, E, A, 12, 7, 14, 7 );
234 P2( A, B, C, D, E, 0, 12, 15, 7 );
235 P2( E, A, B, C, D, 9, 15, 8, 12 );
236 P2( D, E, A, B, C, 5, 9, 12, 7 );
237 P2( C, D, E, A, B, 2, 11, 4, 6 );
238 P2( B, C, D, E, A, 14, 7, 9, 15 );
239 P2( A, B, C, D, E, 11, 13, 1, 13 );
240 P2( E, A, B, C, D, 8, 12, 2, 11 );
241#undef F
242#undef K
243#undef Fp
244#undef Kp
245
246#define F F3
247#define K 0x6ED9EBA1
248#define Fp F3
249#define Kp 0x6D703EF3
250 P2( D, E, A, B, C, 3, 11, 15, 9 );
251 P2( C, D, E, A, B, 10, 13, 5, 7 );
252 P2( B, C, D, E, A, 14, 6, 1, 15 );
253 P2( A, B, C, D, E, 4, 7, 3, 11 );
254 P2( E, A, B, C, D, 9, 14, 7, 8 );
255 P2( D, E, A, B, C, 15, 9, 14, 6 );
256 P2( C, D, E, A, B, 8, 13, 6, 6 );
257 P2( B, C, D, E, A, 1, 15, 9, 14 );
258 P2( A, B, C, D, E, 2, 14, 11, 12 );
259 P2( E, A, B, C, D, 7, 8, 8, 13 );
260 P2( D, E, A, B, C, 0, 13, 12, 5 );
261 P2( C, D, E, A, B, 6, 6, 2, 14 );
262 P2( B, C, D, E, A, 13, 5, 10, 13 );
263 P2( A, B, C, D, E, 11, 12, 0, 13 );
264 P2( E, A, B, C, D, 5, 7, 4, 7 );
265 P2( D, E, A, B, C, 12, 5, 13, 5 );
266#undef F
267#undef K
268#undef Fp
269#undef Kp
270
271#define F F4
272#define K 0x8F1BBCDC
273#define Fp F2
274#define Kp 0x7A6D76E9
275 P2( C, D, E, A, B, 1, 11, 8, 15 );
276 P2( B, C, D, E, A, 9, 12, 6, 5 );
277 P2( A, B, C, D, E, 11, 14, 4, 8 );
278 P2( E, A, B, C, D, 10, 15, 1, 11 );
279 P2( D, E, A, B, C, 0, 14, 3, 14 );
280 P2( C, D, E, A, B, 8, 15, 11, 14 );
281 P2( B, C, D, E, A, 12, 9, 15, 6 );
282 P2( A, B, C, D, E, 4, 8, 0, 14 );
283 P2( E, A, B, C, D, 13, 9, 5, 6 );
284 P2( D, E, A, B, C, 3, 14, 12, 9 );
285 P2( C, D, E, A, B, 7, 5, 2, 12 );
286 P2( B, C, D, E, A, 15, 6, 13, 9 );
287 P2( A, B, C, D, E, 14, 8, 9, 12 );
288 P2( E, A, B, C, D, 5, 6, 7, 5 );
289 P2( D, E, A, B, C, 6, 5, 10, 15 );
290 P2( C, D, E, A, B, 2, 12, 14, 8 );
291#undef F
292#undef K
293#undef Fp
294#undef Kp
295
296#define F F5
297#define K 0xA953FD4E
298#define Fp F1
299#define Kp 0x00000000
300 P2( B, C, D, E, A, 4, 9, 12, 8 );
301 P2( A, B, C, D, E, 0, 15, 15, 5 );
302 P2( E, A, B, C, D, 5, 5, 10, 12 );
303 P2( D, E, A, B, C, 9, 11, 4, 9 );
304 P2( C, D, E, A, B, 7, 6, 1, 12 );
305 P2( B, C, D, E, A, 12, 8, 5, 5 );
306 P2( A, B, C, D, E, 2, 13, 8, 14 );
307 P2( E, A, B, C, D, 10, 12, 7, 6 );
308 P2( D, E, A, B, C, 14, 5, 6, 8 );
309 P2( C, D, E, A, B, 1, 12, 2, 13 );
310 P2( B, C, D, E, A, 3, 13, 13, 6 );
311 P2( A, B, C, D, E, 8, 14, 14, 5 );
312 P2( E, A, B, C, D, 11, 11, 0, 15 );
313 P2( D, E, A, B, C, 6, 8, 3, 13 );
314 P2( C, D, E, A, B, 15, 5, 9, 11 );
315 P2( B, C, D, E, A, 13, 6, 11, 11 );
316#undef F
317#undef K
318#undef Fp
319#undef Kp
320
321 C = ctx->state[1] + C + Dp;
322 ctx->state[1] = ctx->state[2] + D + Ep;
323 ctx->state[2] = ctx->state[3] + E + Ap;
324 ctx->state[3] = ctx->state[4] + A + Bp;
325 ctx->state[4] = ctx->state[0] + B + Cp;
326 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100327
328 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100329}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000330
331#if !defined(MBEDTLS_DEPRECATED_REMOVED)
332void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
333 const unsigned char data[64] )
334{
335 mbedtls_internal_ripemd160_process( ctx, data );
336}
337#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100339
340/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100341 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100342 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100343int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100344 const unsigned char *input,
345 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100346{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100347 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100348 size_t fill;
349 uint32_t left;
350
Brian White12895d12014-04-11 11:29:42 -0400351 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100352 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100353
354 left = ctx->total[0] & 0x3F;
355 fill = 64 - left;
356
357 ctx->total[0] += (uint32_t) ilen;
358 ctx->total[0] &= 0xFFFFFFFF;
359
360 if( ctx->total[0] < (uint32_t) ilen )
361 ctx->total[1]++;
362
363 if( left && ilen >= fill )
364 {
365 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100366
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100367 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100368 return( ret );
369
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100370 input += fill;
371 ilen -= fill;
372 left = 0;
373 }
374
375 while( ilen >= 64 )
376 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100377 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100378 return( ret );
379
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100380 input += 64;
381 ilen -= 64;
382 }
383
384 if( ilen > 0 )
385 {
386 memcpy( (void *) (ctx->buffer + left), input, ilen );
387 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100388
389 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100390}
391
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000392#if !defined(MBEDTLS_DEPRECATED_REMOVED)
393void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
394 const unsigned char *input,
395 size_t ilen )
396{
397 mbedtls_ripemd160_update_ret( ctx, input, ilen );
398}
399#endif
400
Paul Bakker61b699e2014-01-22 13:35:29 +0100401static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100402{
403 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
404 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
405 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
406 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
407};
408
409/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100410 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100411 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100412int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100413 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100414{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100415 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100416 uint32_t last, padn;
417 uint32_t high, low;
418 unsigned char msglen[8];
419
420 high = ( ctx->total[0] >> 29 )
421 | ( ctx->total[1] << 3 );
422 low = ( ctx->total[0] << 3 );
423
424 PUT_UINT32_LE( low, msglen, 0 );
425 PUT_UINT32_LE( high, msglen, 4 );
426
427 last = ctx->total[0] & 0x3F;
428 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
429
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100430 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100431 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100432 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100433
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100434 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100435 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100436 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100437
438 PUT_UINT32_LE( ctx->state[0], output, 0 );
439 PUT_UINT32_LE( ctx->state[1], output, 4 );
440 PUT_UINT32_LE( ctx->state[2], output, 8 );
441 PUT_UINT32_LE( ctx->state[3], output, 12 );
442 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100443
444 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100445}
446
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000447#if !defined(MBEDTLS_DEPRECATED_REMOVED)
448void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
449 unsigned char output[20] )
450{
451 mbedtls_ripemd160_finish_ret( ctx, output );
452}
453#endif
454
Gilles Peskine342d9282018-01-23 18:21:21 +0100455#endif /* ! MBEDTLS_RIPEMD160_ALT */
456
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100457/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100458 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100459 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100460int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100461 size_t ilen,
462 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100463{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100464 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100468
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100469 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100470 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100471
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100472 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100473 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100474
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100475 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100476 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100477
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100478exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100480
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100481 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100482}
483
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000484#if !defined(MBEDTLS_DEPRECATED_REMOVED)
485void mbedtls_ripemd160( const unsigned char *input,
486 size_t ilen,
487 unsigned char output[20] )
488{
489 mbedtls_ripemd160_ret( input, ilen, output );
490}
491#endif
492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100494/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100495 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100497 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100498#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100499static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100500{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100501 { "" },
502 { "a" },
503 { "abc" },
504 { "message digest" },
505 { "abcdefghijklmnopqrstuvwxyz" },
506 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
507 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
508 { "12345678901234567890123456789012345678901234567890123456789012"
509 "345678901234567890" },
510};
511
512static const size_t ripemd160_test_strlen[TESTS] =
513{
514 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100515};
516
Paul Bakker61b699e2014-01-22 13:35:29 +0100517static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100518{
519 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
520 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
521 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
522 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
523 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
524 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
525 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
526 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
527 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
528 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
529 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
530 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
531 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
532 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
533 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
534 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
535};
536
537/*
538 * Checkup routine
539 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100541{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100542 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100543 unsigned char output[20];
544
545 memset( output, 0, sizeof output );
546
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100547 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100548 {
549 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100551
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100552 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100553 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100554 if( ret != 0 )
555 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100556
Paul Bakker61b699e2014-01-22 13:35:29 +0100557 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100558 {
559 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100560 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100561 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100562
563 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100565 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100566
Paul Bakker4400ecc2016-07-19 14:41:43 +0100567 if( verbose != 0 )
568 mbedtls_printf( "\n" );
569
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100570 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100571
572fail:
573 if( verbose != 0 )
574 mbedtls_printf( "failed\n" );
575
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100576 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100577}
578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581#endif /* MBEDTLS_RIPEMD160_C */