blob: f5868e287ae02b64c065f161050bb37ae65823ca [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ú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 * **********
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"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010064
Rich Evans00ab4702015-02-06 13:43:58 +000065#include <string.h>
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if defined(MBEDTLS_SELF_TEST)
68#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000069#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010070#else
Rich Evans00ab4702015-02-06 13:43:58 +000071#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#define mbedtls_printf printf
73#endif /* MBEDTLS_PLATFORM_C */
74#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010075
Gilles Peskine342d9282018-01-23 18:21:21 +010076#if !defined(MBEDTLS_RIPEMD160_ALT)
77
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010078/*
79 * 32-bit integer manipulation macros (little endian)
80 */
81#ifndef GET_UINT32_LE
82#define GET_UINT32_LE(n,b,i) \
83{ \
84 (n) = ( (uint32_t) (b)[(i) ] ) \
85 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
86 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
87 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
88}
89#endif
90
91#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000092#define PUT_UINT32_LE(n,b,i) \
93{ \
94 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
95 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
96 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
97 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010098}
99#endif
100
Paul Bakker34617722014-06-13 17:20:13 +0200101/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +0200103 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
104}
105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200107{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200109}
110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200112{
113 if( ctx == NULL )
114 return;
115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116 mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200117}
118
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200119void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
120 const mbedtls_ripemd160_context *src )
121{
122 *dst = *src;
123}
124
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100125/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100126 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100127 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100128int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100129{
130 ctx->total[0] = 0;
131 ctx->total[1] = 0;
132
133 ctx->state[0] = 0x67452301;
134 ctx->state[1] = 0xEFCDAB89;
135 ctx->state[2] = 0x98BADCFE;
136 ctx->state[3] = 0x10325476;
137 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100138
139 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100140}
141
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000142#if !defined(MBEDTLS_DEPRECATED_REMOVED)
143void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
144{
145 mbedtls_ripemd160_starts_ret( ctx );
146}
147#endif
148
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100150/*
151 * Process one block
152 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100153int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
154 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100155{
156 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
157
158 GET_UINT32_LE( X[ 0], data, 0 );
159 GET_UINT32_LE( X[ 1], data, 4 );
160 GET_UINT32_LE( X[ 2], data, 8 );
161 GET_UINT32_LE( X[ 3], data, 12 );
162 GET_UINT32_LE( X[ 4], data, 16 );
163 GET_UINT32_LE( X[ 5], data, 20 );
164 GET_UINT32_LE( X[ 6], data, 24 );
165 GET_UINT32_LE( X[ 7], data, 28 );
166 GET_UINT32_LE( X[ 8], data, 32 );
167 GET_UINT32_LE( X[ 9], data, 36 );
168 GET_UINT32_LE( X[10], data, 40 );
169 GET_UINT32_LE( X[11], data, 44 );
170 GET_UINT32_LE( X[12], data, 48 );
171 GET_UINT32_LE( X[13], data, 52 );
172 GET_UINT32_LE( X[14], data, 56 );
173 GET_UINT32_LE( X[15], data, 60 );
174
175 A = Ap = ctx->state[0];
176 B = Bp = ctx->state[1];
177 C = Cp = ctx->state[2];
178 D = Dp = ctx->state[3];
179 E = Ep = ctx->state[4];
180
181#define F1( x, y, z ) ( x ^ y ^ z )
182#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
183#define F3( x, y, z ) ( ( x | ~y ) ^ z )
184#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
185#define F5( x, y, z ) ( x ^ ( y | ~z ) )
186
187#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
188
189#define P( a, b, c, d, e, r, s, f, k ) \
190 a += f( b, c, d ) + X[r] + k; \
191 a = S( a, s ) + e; \
192 c = S( c, 10 );
193
194#define P2( a, b, c, d, e, r, s, rp, sp ) \
195 P( a, b, c, d, e, r, s, F, K ); \
196 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
197
198#define F F1
199#define K 0x00000000
200#define Fp F5
201#define Kp 0x50A28BE6
202 P2( A, B, C, D, E, 0, 11, 5, 8 );
203 P2( E, A, B, C, D, 1, 14, 14, 9 );
204 P2( D, E, A, B, C, 2, 15, 7, 9 );
205 P2( C, D, E, A, B, 3, 12, 0, 11 );
206 P2( B, C, D, E, A, 4, 5, 9, 13 );
207 P2( A, B, C, D, E, 5, 8, 2, 15 );
208 P2( E, A, B, C, D, 6, 7, 11, 15 );
209 P2( D, E, A, B, C, 7, 9, 4, 5 );
210 P2( C, D, E, A, B, 8, 11, 13, 7 );
211 P2( B, C, D, E, A, 9, 13, 6, 7 );
212 P2( A, B, C, D, E, 10, 14, 15, 8 );
213 P2( E, A, B, C, D, 11, 15, 8, 11 );
214 P2( D, E, A, B, C, 12, 6, 1, 14 );
215 P2( C, D, E, A, B, 13, 7, 10, 14 );
216 P2( B, C, D, E, A, 14, 9, 3, 12 );
217 P2( A, B, C, D, E, 15, 8, 12, 6 );
218#undef F
219#undef K
220#undef Fp
221#undef Kp
222
223#define F F2
224#define K 0x5A827999
225#define Fp F4
226#define Kp 0x5C4DD124
227 P2( E, A, B, C, D, 7, 7, 6, 9 );
228 P2( D, E, A, B, C, 4, 6, 11, 13 );
229 P2( C, D, E, A, B, 13, 8, 3, 15 );
230 P2( B, C, D, E, A, 1, 13, 7, 7 );
231 P2( A, B, C, D, E, 10, 11, 0, 12 );
232 P2( E, A, B, C, D, 6, 9, 13, 8 );
233 P2( D, E, A, B, C, 15, 7, 5, 9 );
234 P2( C, D, E, A, B, 3, 15, 10, 11 );
235 P2( B, C, D, E, A, 12, 7, 14, 7 );
236 P2( A, B, C, D, E, 0, 12, 15, 7 );
237 P2( E, A, B, C, D, 9, 15, 8, 12 );
238 P2( D, E, A, B, C, 5, 9, 12, 7 );
239 P2( C, D, E, A, B, 2, 11, 4, 6 );
240 P2( B, C, D, E, A, 14, 7, 9, 15 );
241 P2( A, B, C, D, E, 11, 13, 1, 13 );
242 P2( E, A, B, C, D, 8, 12, 2, 11 );
243#undef F
244#undef K
245#undef Fp
246#undef Kp
247
248#define F F3
249#define K 0x6ED9EBA1
250#define Fp F3
251#define Kp 0x6D703EF3
252 P2( D, E, A, B, C, 3, 11, 15, 9 );
253 P2( C, D, E, A, B, 10, 13, 5, 7 );
254 P2( B, C, D, E, A, 14, 6, 1, 15 );
255 P2( A, B, C, D, E, 4, 7, 3, 11 );
256 P2( E, A, B, C, D, 9, 14, 7, 8 );
257 P2( D, E, A, B, C, 15, 9, 14, 6 );
258 P2( C, D, E, A, B, 8, 13, 6, 6 );
259 P2( B, C, D, E, A, 1, 15, 9, 14 );
260 P2( A, B, C, D, E, 2, 14, 11, 12 );
261 P2( E, A, B, C, D, 7, 8, 8, 13 );
262 P2( D, E, A, B, C, 0, 13, 12, 5 );
263 P2( C, D, E, A, B, 6, 6, 2, 14 );
264 P2( B, C, D, E, A, 13, 5, 10, 13 );
265 P2( A, B, C, D, E, 11, 12, 0, 13 );
266 P2( E, A, B, C, D, 5, 7, 4, 7 );
267 P2( D, E, A, B, C, 12, 5, 13, 5 );
268#undef F
269#undef K
270#undef Fp
271#undef Kp
272
273#define F F4
274#define K 0x8F1BBCDC
275#define Fp F2
276#define Kp 0x7A6D76E9
277 P2( C, D, E, A, B, 1, 11, 8, 15 );
278 P2( B, C, D, E, A, 9, 12, 6, 5 );
279 P2( A, B, C, D, E, 11, 14, 4, 8 );
280 P2( E, A, B, C, D, 10, 15, 1, 11 );
281 P2( D, E, A, B, C, 0, 14, 3, 14 );
282 P2( C, D, E, A, B, 8, 15, 11, 14 );
283 P2( B, C, D, E, A, 12, 9, 15, 6 );
284 P2( A, B, C, D, E, 4, 8, 0, 14 );
285 P2( E, A, B, C, D, 13, 9, 5, 6 );
286 P2( D, E, A, B, C, 3, 14, 12, 9 );
287 P2( C, D, E, A, B, 7, 5, 2, 12 );
288 P2( B, C, D, E, A, 15, 6, 13, 9 );
289 P2( A, B, C, D, E, 14, 8, 9, 12 );
290 P2( E, A, B, C, D, 5, 6, 7, 5 );
291 P2( D, E, A, B, C, 6, 5, 10, 15 );
292 P2( C, D, E, A, B, 2, 12, 14, 8 );
293#undef F
294#undef K
295#undef Fp
296#undef Kp
297
298#define F F5
299#define K 0xA953FD4E
300#define Fp F1
301#define Kp 0x00000000
302 P2( B, C, D, E, A, 4, 9, 12, 8 );
303 P2( A, B, C, D, E, 0, 15, 15, 5 );
304 P2( E, A, B, C, D, 5, 5, 10, 12 );
305 P2( D, E, A, B, C, 9, 11, 4, 9 );
306 P2( C, D, E, A, B, 7, 6, 1, 12 );
307 P2( B, C, D, E, A, 12, 8, 5, 5 );
308 P2( A, B, C, D, E, 2, 13, 8, 14 );
309 P2( E, A, B, C, D, 10, 12, 7, 6 );
310 P2( D, E, A, B, C, 14, 5, 6, 8 );
311 P2( C, D, E, A, B, 1, 12, 2, 13 );
312 P2( B, C, D, E, A, 3, 13, 13, 6 );
313 P2( A, B, C, D, E, 8, 14, 14, 5 );
314 P2( E, A, B, C, D, 11, 11, 0, 15 );
315 P2( D, E, A, B, C, 6, 8, 3, 13 );
316 P2( C, D, E, A, B, 15, 5, 9, 11 );
317 P2( B, C, D, E, A, 13, 6, 11, 11 );
318#undef F
319#undef K
320#undef Fp
321#undef Kp
322
323 C = ctx->state[1] + C + Dp;
324 ctx->state[1] = ctx->state[2] + D + Ep;
325 ctx->state[2] = ctx->state[3] + E + Ap;
326 ctx->state[3] = ctx->state[4] + A + Bp;
327 ctx->state[4] = ctx->state[0] + B + Cp;
328 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100329
330 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100331}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000332
333#if !defined(MBEDTLS_DEPRECATED_REMOVED)
334void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
335 const unsigned char data[64] )
336{
337 mbedtls_internal_ripemd160_process( ctx, data );
338}
339#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100341
342/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100343 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100344 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100345int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100346 const unsigned char *input,
347 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100348{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100349 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100350 size_t fill;
351 uint32_t left;
352
Brian White12895d12014-04-11 11:29:42 -0400353 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100354 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100355
356 left = ctx->total[0] & 0x3F;
357 fill = 64 - left;
358
359 ctx->total[0] += (uint32_t) ilen;
360 ctx->total[0] &= 0xFFFFFFFF;
361
362 if( ctx->total[0] < (uint32_t) ilen )
363 ctx->total[1]++;
364
365 if( left && ilen >= fill )
366 {
367 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100368
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100369 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100370 return( ret );
371
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100372 input += fill;
373 ilen -= fill;
374 left = 0;
375 }
376
377 while( ilen >= 64 )
378 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100379 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100380 return( ret );
381
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100382 input += 64;
383 ilen -= 64;
384 }
385
386 if( ilen > 0 )
387 {
388 memcpy( (void *) (ctx->buffer + left), input, ilen );
389 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100390
391 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100392}
393
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000394#if !defined(MBEDTLS_DEPRECATED_REMOVED)
395void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
396 const unsigned char *input,
397 size_t ilen )
398{
399 mbedtls_ripemd160_update_ret( ctx, input, ilen );
400}
401#endif
402
Paul Bakker61b699e2014-01-22 13:35:29 +0100403static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100404{
405 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
408 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
409};
410
411/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100412 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100413 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100414int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100415 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100416{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100417 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100418 uint32_t last, padn;
419 uint32_t high, low;
420 unsigned char msglen[8];
421
422 high = ( ctx->total[0] >> 29 )
423 | ( ctx->total[1] << 3 );
424 low = ( ctx->total[0] << 3 );
425
426 PUT_UINT32_LE( low, msglen, 0 );
427 PUT_UINT32_LE( high, msglen, 4 );
428
429 last = ctx->total[0] & 0x3F;
430 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
431
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100432 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100433 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100434 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100435
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100436 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100437 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100438 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100439
440 PUT_UINT32_LE( ctx->state[0], output, 0 );
441 PUT_UINT32_LE( ctx->state[1], output, 4 );
442 PUT_UINT32_LE( ctx->state[2], output, 8 );
443 PUT_UINT32_LE( ctx->state[3], output, 12 );
444 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100445
446 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100447}
448
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000449#if !defined(MBEDTLS_DEPRECATED_REMOVED)
450void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
451 unsigned char output[20] )
452{
453 mbedtls_ripemd160_finish_ret( ctx, output );
454}
455#endif
456
Gilles Peskine342d9282018-01-23 18:21:21 +0100457#endif /* ! MBEDTLS_RIPEMD160_ALT */
458
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100459/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100460 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100461 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100462int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100463 size_t ilen,
464 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100465{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100466 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100470
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100471 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100472 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100473
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100474 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 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_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100478 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100479
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100480exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100482
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100483 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100484}
485
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000486#if !defined(MBEDTLS_DEPRECATED_REMOVED)
487void mbedtls_ripemd160( const unsigned char *input,
488 size_t ilen,
489 unsigned char output[20] )
490{
491 mbedtls_ripemd160_ret( input, ilen, output );
492}
493#endif
494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100496/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100497 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100499 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100500#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100501static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100502{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100503 { "" },
504 { "a" },
505 { "abc" },
506 { "message digest" },
507 { "abcdefghijklmnopqrstuvwxyz" },
508 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
509 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
510 { "12345678901234567890123456789012345678901234567890123456789012"
511 "345678901234567890" },
512};
513
514static const size_t ripemd160_test_strlen[TESTS] =
515{
516 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100517};
518
Paul Bakker61b699e2014-01-22 13:35:29 +0100519static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100520{
521 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
522 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
523 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
524 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
525 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
526 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
527 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
528 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
529 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
530 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
531 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
532 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
533 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
534 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
535 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
536 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
537};
538
539/*
540 * Checkup routine
541 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100543{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100544 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100545 unsigned char output[20];
546
547 memset( output, 0, sizeof output );
548
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100549 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100550 {
551 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100553
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100554 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100555 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100556 if( ret != 0 )
557 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100558
Paul Bakker61b699e2014-01-22 13:35:29 +0100559 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100560 {
561 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100562 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100563 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100564
565 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100567 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100568
Paul Bakker4400ecc2016-07-19 14:41:43 +0100569 if( verbose != 0 )
570 mbedtls_printf( "\n" );
571
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100572 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100573
574fail:
575 if( verbose != 0 )
576 mbedtls_printf( "failed\n" );
577
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100578 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100579}
580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583#endif /* MBEDTLS_RIPEMD160_C */