blob: b85b117c6a700520b21fad15077971d4c7b9956b [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010020 */
21
22/*
23 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020024 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010025 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/ripemd160.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#define mbedtls_printf printf
46#endif /* MBEDTLS_PLATFORM_C */
47#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Gilles Peskine342d9282018-01-23 18:21:21 +010049#if !defined(MBEDTLS_RIPEMD160_ALT)
50
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010051/*
52 * 32-bit integer manipulation macros (little endian)
53 */
54#ifndef GET_UINT32_LE
55#define GET_UINT32_LE(n,b,i) \
56{ \
57 (n) = ( (uint32_t) (b)[(i) ] ) \
58 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
59 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
60 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
61}
62#endif
63
64#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000065#define PUT_UINT32_LE(n,b,i) \
66{ \
67 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
68 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
69 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
70 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010071}
72#endif
73
Paul Bakker34617722014-06-13 17:20:13 +020074/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020076 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
77}
78
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020080{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020082}
83
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020085{
86 if( ctx == NULL )
87 return;
88
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020089 mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020090}
91
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020092void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
93 const mbedtls_ripemd160_context *src )
94{
95 *dst = *src;
96}
97
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010098/*
Paul Bakker61b699e2014-01-22 13:35:29 +010099 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100100 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100101int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100102{
103 ctx->total[0] = 0;
104 ctx->total[1] = 0;
105
106 ctx->state[0] = 0x67452301;
107 ctx->state[1] = 0xEFCDAB89;
108 ctx->state[2] = 0x98BADCFE;
109 ctx->state[3] = 0x10325476;
110 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100111
112 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100113}
114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100116/*
117 * Process one block
118 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100119int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
120 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100121{
122 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
123
124 GET_UINT32_LE( X[ 0], data, 0 );
125 GET_UINT32_LE( X[ 1], data, 4 );
126 GET_UINT32_LE( X[ 2], data, 8 );
127 GET_UINT32_LE( X[ 3], data, 12 );
128 GET_UINT32_LE( X[ 4], data, 16 );
129 GET_UINT32_LE( X[ 5], data, 20 );
130 GET_UINT32_LE( X[ 6], data, 24 );
131 GET_UINT32_LE( X[ 7], data, 28 );
132 GET_UINT32_LE( X[ 8], data, 32 );
133 GET_UINT32_LE( X[ 9], data, 36 );
134 GET_UINT32_LE( X[10], data, 40 );
135 GET_UINT32_LE( X[11], data, 44 );
136 GET_UINT32_LE( X[12], data, 48 );
137 GET_UINT32_LE( X[13], data, 52 );
138 GET_UINT32_LE( X[14], data, 56 );
139 GET_UINT32_LE( X[15], data, 60 );
140
141 A = Ap = ctx->state[0];
142 B = Bp = ctx->state[1];
143 C = Cp = ctx->state[2];
144 D = Dp = ctx->state[3];
145 E = Ep = ctx->state[4];
146
147#define F1( x, y, z ) ( x ^ y ^ z )
148#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
149#define F3( x, y, z ) ( ( x | ~y ) ^ z )
150#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
151#define F5( x, y, z ) ( x ^ ( y | ~z ) )
152
153#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
154
155#define P( a, b, c, d, e, r, s, f, k ) \
156 a += f( b, c, d ) + X[r] + k; \
157 a = S( a, s ) + e; \
158 c = S( c, 10 );
159
160#define P2( a, b, c, d, e, r, s, rp, sp ) \
161 P( a, b, c, d, e, r, s, F, K ); \
162 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
163
164#define F F1
165#define K 0x00000000
166#define Fp F5
167#define Kp 0x50A28BE6
168 P2( A, B, C, D, E, 0, 11, 5, 8 );
169 P2( E, A, B, C, D, 1, 14, 14, 9 );
170 P2( D, E, A, B, C, 2, 15, 7, 9 );
171 P2( C, D, E, A, B, 3, 12, 0, 11 );
172 P2( B, C, D, E, A, 4, 5, 9, 13 );
173 P2( A, B, C, D, E, 5, 8, 2, 15 );
174 P2( E, A, B, C, D, 6, 7, 11, 15 );
175 P2( D, E, A, B, C, 7, 9, 4, 5 );
176 P2( C, D, E, A, B, 8, 11, 13, 7 );
177 P2( B, C, D, E, A, 9, 13, 6, 7 );
178 P2( A, B, C, D, E, 10, 14, 15, 8 );
179 P2( E, A, B, C, D, 11, 15, 8, 11 );
180 P2( D, E, A, B, C, 12, 6, 1, 14 );
181 P2( C, D, E, A, B, 13, 7, 10, 14 );
182 P2( B, C, D, E, A, 14, 9, 3, 12 );
183 P2( A, B, C, D, E, 15, 8, 12, 6 );
184#undef F
185#undef K
186#undef Fp
187#undef Kp
188
189#define F F2
190#define K 0x5A827999
191#define Fp F4
192#define Kp 0x5C4DD124
193 P2( E, A, B, C, D, 7, 7, 6, 9 );
194 P2( D, E, A, B, C, 4, 6, 11, 13 );
195 P2( C, D, E, A, B, 13, 8, 3, 15 );
196 P2( B, C, D, E, A, 1, 13, 7, 7 );
197 P2( A, B, C, D, E, 10, 11, 0, 12 );
198 P2( E, A, B, C, D, 6, 9, 13, 8 );
199 P2( D, E, A, B, C, 15, 7, 5, 9 );
200 P2( C, D, E, A, B, 3, 15, 10, 11 );
201 P2( B, C, D, E, A, 12, 7, 14, 7 );
202 P2( A, B, C, D, E, 0, 12, 15, 7 );
203 P2( E, A, B, C, D, 9, 15, 8, 12 );
204 P2( D, E, A, B, C, 5, 9, 12, 7 );
205 P2( C, D, E, A, B, 2, 11, 4, 6 );
206 P2( B, C, D, E, A, 14, 7, 9, 15 );
207 P2( A, B, C, D, E, 11, 13, 1, 13 );
208 P2( E, A, B, C, D, 8, 12, 2, 11 );
209#undef F
210#undef K
211#undef Fp
212#undef Kp
213
214#define F F3
215#define K 0x6ED9EBA1
216#define Fp F3
217#define Kp 0x6D703EF3
218 P2( D, E, A, B, C, 3, 11, 15, 9 );
219 P2( C, D, E, A, B, 10, 13, 5, 7 );
220 P2( B, C, D, E, A, 14, 6, 1, 15 );
221 P2( A, B, C, D, E, 4, 7, 3, 11 );
222 P2( E, A, B, C, D, 9, 14, 7, 8 );
223 P2( D, E, A, B, C, 15, 9, 14, 6 );
224 P2( C, D, E, A, B, 8, 13, 6, 6 );
225 P2( B, C, D, E, A, 1, 15, 9, 14 );
226 P2( A, B, C, D, E, 2, 14, 11, 12 );
227 P2( E, A, B, C, D, 7, 8, 8, 13 );
228 P2( D, E, A, B, C, 0, 13, 12, 5 );
229 P2( C, D, E, A, B, 6, 6, 2, 14 );
230 P2( B, C, D, E, A, 13, 5, 10, 13 );
231 P2( A, B, C, D, E, 11, 12, 0, 13 );
232 P2( E, A, B, C, D, 5, 7, 4, 7 );
233 P2( D, E, A, B, C, 12, 5, 13, 5 );
234#undef F
235#undef K
236#undef Fp
237#undef Kp
238
239#define F F4
240#define K 0x8F1BBCDC
241#define Fp F2
242#define Kp 0x7A6D76E9
243 P2( C, D, E, A, B, 1, 11, 8, 15 );
244 P2( B, C, D, E, A, 9, 12, 6, 5 );
245 P2( A, B, C, D, E, 11, 14, 4, 8 );
246 P2( E, A, B, C, D, 10, 15, 1, 11 );
247 P2( D, E, A, B, C, 0, 14, 3, 14 );
248 P2( C, D, E, A, B, 8, 15, 11, 14 );
249 P2( B, C, D, E, A, 12, 9, 15, 6 );
250 P2( A, B, C, D, E, 4, 8, 0, 14 );
251 P2( E, A, B, C, D, 13, 9, 5, 6 );
252 P2( D, E, A, B, C, 3, 14, 12, 9 );
253 P2( C, D, E, A, B, 7, 5, 2, 12 );
254 P2( B, C, D, E, A, 15, 6, 13, 9 );
255 P2( A, B, C, D, E, 14, 8, 9, 12 );
256 P2( E, A, B, C, D, 5, 6, 7, 5 );
257 P2( D, E, A, B, C, 6, 5, 10, 15 );
258 P2( C, D, E, A, B, 2, 12, 14, 8 );
259#undef F
260#undef K
261#undef Fp
262#undef Kp
263
264#define F F5
265#define K 0xA953FD4E
266#define Fp F1
267#define Kp 0x00000000
268 P2( B, C, D, E, A, 4, 9, 12, 8 );
269 P2( A, B, C, D, E, 0, 15, 15, 5 );
270 P2( E, A, B, C, D, 5, 5, 10, 12 );
271 P2( D, E, A, B, C, 9, 11, 4, 9 );
272 P2( C, D, E, A, B, 7, 6, 1, 12 );
273 P2( B, C, D, E, A, 12, 8, 5, 5 );
274 P2( A, B, C, D, E, 2, 13, 8, 14 );
275 P2( E, A, B, C, D, 10, 12, 7, 6 );
276 P2( D, E, A, B, C, 14, 5, 6, 8 );
277 P2( C, D, E, A, B, 1, 12, 2, 13 );
278 P2( B, C, D, E, A, 3, 13, 13, 6 );
279 P2( A, B, C, D, E, 8, 14, 14, 5 );
280 P2( E, A, B, C, D, 11, 11, 0, 15 );
281 P2( D, E, A, B, C, 6, 8, 3, 13 );
282 P2( C, D, E, A, B, 15, 5, 9, 11 );
283 P2( B, C, D, E, A, 13, 6, 11, 11 );
284#undef F
285#undef K
286#undef Fp
287#undef Kp
288
289 C = ctx->state[1] + C + Dp;
290 ctx->state[1] = ctx->state[2] + D + Ep;
291 ctx->state[2] = ctx->state[3] + E + Ap;
292 ctx->state[3] = ctx->state[4] + A + Bp;
293 ctx->state[4] = ctx->state[0] + B + Cp;
294 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100295
296 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100297}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100299
300/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100301 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100302 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100303int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100304 const unsigned char *input,
305 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100306{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100307 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100308 size_t fill;
309 uint32_t left;
310
Brian White12895d12014-04-11 11:29:42 -0400311 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100312 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100313
314 left = ctx->total[0] & 0x3F;
315 fill = 64 - left;
316
317 ctx->total[0] += (uint32_t) ilen;
318 ctx->total[0] &= 0xFFFFFFFF;
319
320 if( ctx->total[0] < (uint32_t) ilen )
321 ctx->total[1]++;
322
323 if( left && ilen >= fill )
324 {
325 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100326
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100327 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100328 return( ret );
329
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100330 input += fill;
331 ilen -= fill;
332 left = 0;
333 }
334
335 while( ilen >= 64 )
336 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100337 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100338 return( ret );
339
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100340 input += 64;
341 ilen -= 64;
342 }
343
344 if( ilen > 0 )
345 {
346 memcpy( (void *) (ctx->buffer + left), input, ilen );
347 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100348
349 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100350}
351
Paul Bakker61b699e2014-01-22 13:35:29 +0100352static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100353{
354 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
355 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
357 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
358};
359
360/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100361 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100362 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100363int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100364 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100365{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100366 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100367 uint32_t last, padn;
368 uint32_t high, low;
369 unsigned char msglen[8];
370
371 high = ( ctx->total[0] >> 29 )
372 | ( ctx->total[1] << 3 );
373 low = ( ctx->total[0] << 3 );
374
375 PUT_UINT32_LE( low, msglen, 0 );
376 PUT_UINT32_LE( high, msglen, 4 );
377
378 last = ctx->total[0] & 0x3F;
379 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
380
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100381 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100382 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100383 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100384
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100385 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100386 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100387 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100388
389 PUT_UINT32_LE( ctx->state[0], output, 0 );
390 PUT_UINT32_LE( ctx->state[1], output, 4 );
391 PUT_UINT32_LE( ctx->state[2], output, 8 );
392 PUT_UINT32_LE( ctx->state[3], output, 12 );
393 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100394
395 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100396}
397
Gilles Peskine342d9282018-01-23 18:21:21 +0100398#endif /* ! MBEDTLS_RIPEMD160_ALT */
399
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100400/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100401 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100402 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100403int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100404 size_t ilen,
405 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100406{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100407 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100409
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200410 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100411
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100412 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100413 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100414
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100415 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100416 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100417
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100418 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100419 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100420
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100421exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100423
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100424 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100425}
426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100428/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100429 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100431 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100432#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100433static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100434{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100435 { "" },
436 { "a" },
437 { "abc" },
438 { "message digest" },
439 { "abcdefghijklmnopqrstuvwxyz" },
440 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
441 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
442 { "12345678901234567890123456789012345678901234567890123456789012"
443 "345678901234567890" },
444};
445
446static const size_t ripemd160_test_strlen[TESTS] =
447{
448 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100449};
450
Paul Bakker61b699e2014-01-22 13:35:29 +0100451static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100452{
453 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
454 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
455 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
456 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
457 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
458 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
459 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
460 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
461 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
462 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
463 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
464 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
465 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
466 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
467 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
468 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
469};
470
471/*
472 * Checkup routine
473 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100476 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100477 unsigned char output[20];
478
479 memset( output, 0, sizeof output );
480
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100481 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100482 {
483 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100486 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100487 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100488 if( ret != 0 )
489 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100490
Paul Bakker61b699e2014-01-22 13:35:29 +0100491 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100492 {
493 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100494 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100495 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100496
497 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100499 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100500
Paul Bakker4400ecc2016-07-19 14:41:43 +0100501 if( verbose != 0 )
502 mbedtls_printf( "\n" );
503
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100504 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100505
506fail:
507 if( verbose != 0 )
508 mbedtls_printf( "failed\n" );
509
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100510 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100511}
512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100514
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515#endif /* MBEDTLS_RIPEMD160_C */