blob: f58507773e6458bf2e28065f9816225d81055593 [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
gabor-mezei-armcb3a7422020-08-19 14:03:06 +0200328 /* Zeroise variables to clear sensitive data from memory. */
329 mbedtls_zeroize( &A, sizeof( A ) );
330 mbedtls_zeroize( &B, sizeof( B ) );
331 mbedtls_zeroize( &C, sizeof( C ) );
332 mbedtls_zeroize( &D, sizeof( D ) );
333 mbedtls_zeroize( &E, sizeof( E ) );
334 mbedtls_zeroize( &Ap, sizeof( Ap ) );
335 mbedtls_zeroize( &Bp, sizeof( Bp ) );
336 mbedtls_zeroize( &Cp, sizeof( Cp ) );
337 mbedtls_zeroize( &Dp, sizeof( Dp ) );
338 mbedtls_zeroize( &Ep, sizeof( Ep ) );
339 mbedtls_zeroize( &X, sizeof( X ) );
340
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100341 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100342}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000343
344#if !defined(MBEDTLS_DEPRECATED_REMOVED)
345void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
346 const unsigned char data[64] )
347{
348 mbedtls_internal_ripemd160_process( ctx, data );
349}
350#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100352
353/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100354 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100355 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100356int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100357 const unsigned char *input,
358 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100359{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100360 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100361 size_t fill;
362 uint32_t left;
363
Brian White12895d12014-04-11 11:29:42 -0400364 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100365 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100366
367 left = ctx->total[0] & 0x3F;
368 fill = 64 - left;
369
370 ctx->total[0] += (uint32_t) ilen;
371 ctx->total[0] &= 0xFFFFFFFF;
372
373 if( ctx->total[0] < (uint32_t) ilen )
374 ctx->total[1]++;
375
376 if( left && ilen >= fill )
377 {
378 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100379
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100380 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100381 return( ret );
382
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100383 input += fill;
384 ilen -= fill;
385 left = 0;
386 }
387
388 while( ilen >= 64 )
389 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100390 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100391 return( ret );
392
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100393 input += 64;
394 ilen -= 64;
395 }
396
397 if( ilen > 0 )
398 {
399 memcpy( (void *) (ctx->buffer + left), input, ilen );
400 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100401
402 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100403}
404
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000405#if !defined(MBEDTLS_DEPRECATED_REMOVED)
406void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
407 const unsigned char *input,
408 size_t ilen )
409{
410 mbedtls_ripemd160_update_ret( ctx, input, ilen );
411}
412#endif
413
Paul Bakker61b699e2014-01-22 13:35:29 +0100414static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100415{
416 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
417 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
418 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
419 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
420};
421
422/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100423 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100424 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100425int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100426 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100427{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100428 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100429 uint32_t last, padn;
430 uint32_t high, low;
431 unsigned char msglen[8];
432
433 high = ( ctx->total[0] >> 29 )
434 | ( ctx->total[1] << 3 );
435 low = ( ctx->total[0] << 3 );
436
437 PUT_UINT32_LE( low, msglen, 0 );
438 PUT_UINT32_LE( high, msglen, 4 );
439
440 last = ctx->total[0] & 0x3F;
441 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
442
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100443 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100444 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100445 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100446
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100447 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100448 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100449 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100450
451 PUT_UINT32_LE( ctx->state[0], output, 0 );
452 PUT_UINT32_LE( ctx->state[1], output, 4 );
453 PUT_UINT32_LE( ctx->state[2], output, 8 );
454 PUT_UINT32_LE( ctx->state[3], output, 12 );
455 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100456
457 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100458}
459
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000460#if !defined(MBEDTLS_DEPRECATED_REMOVED)
461void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
462 unsigned char output[20] )
463{
464 mbedtls_ripemd160_finish_ret( ctx, output );
465}
466#endif
467
Gilles Peskine342d9282018-01-23 18:21:21 +0100468#endif /* ! MBEDTLS_RIPEMD160_ALT */
469
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100470/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100471 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100472 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100473int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100474 size_t ilen,
475 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100476{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100477 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100481
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100482 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100483 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100484
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100485 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100486 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100487
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100488 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100489 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100490
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100491exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100493
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100494 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100495}
496
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000497#if !defined(MBEDTLS_DEPRECATED_REMOVED)
498void mbedtls_ripemd160( const unsigned char *input,
499 size_t ilen,
500 unsigned char output[20] )
501{
502 mbedtls_ripemd160_ret( input, ilen, output );
503}
504#endif
505
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100507/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100508 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100510 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100511#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100512static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100513{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100514 { "" },
515 { "a" },
516 { "abc" },
517 { "message digest" },
518 { "abcdefghijklmnopqrstuvwxyz" },
519 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
520 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
521 { "12345678901234567890123456789012345678901234567890123456789012"
522 "345678901234567890" },
523};
524
525static const size_t ripemd160_test_strlen[TESTS] =
526{
527 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100528};
529
Paul Bakker61b699e2014-01-22 13:35:29 +0100530static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100531{
532 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
533 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
534 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
535 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
536 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
537 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
538 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
539 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
540 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
541 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
542 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
543 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
544 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
545 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
546 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
547 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
548};
549
550/*
551 * Checkup routine
552 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100554{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100555 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100556 unsigned char output[20];
557
558 memset( output, 0, sizeof output );
559
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100560 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100561 {
562 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100564
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100565 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100566 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100567 if( ret != 0 )
568 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100569
Paul Bakker61b699e2014-01-22 13:35:29 +0100570 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100571 {
572 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100573 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100574 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100575
576 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100578 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100579
Paul Bakker4400ecc2016-07-19 14:41:43 +0100580 if( verbose != 0 )
581 mbedtls_printf( "\n" );
582
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100583 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100584
585fail:
586 if( verbose != 0 )
587 mbedtls_printf( "failed\n" );
588
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100589 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100590}
591
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100593
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594#endif /* MBEDTLS_RIPEMD160_C */