blob: 2ba48b7fdb7a3daa6c7c69a641724c28273d2b5e [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
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000115#if !defined(MBEDTLS_DEPRECATED_REMOVED)
116void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
117{
118 mbedtls_ripemd160_starts_ret( ctx );
119}
120#endif
121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100123/*
124 * Process one block
125 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100126int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
127 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100128{
129 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
130
131 GET_UINT32_LE( X[ 0], data, 0 );
132 GET_UINT32_LE( X[ 1], data, 4 );
133 GET_UINT32_LE( X[ 2], data, 8 );
134 GET_UINT32_LE( X[ 3], data, 12 );
135 GET_UINT32_LE( X[ 4], data, 16 );
136 GET_UINT32_LE( X[ 5], data, 20 );
137 GET_UINT32_LE( X[ 6], data, 24 );
138 GET_UINT32_LE( X[ 7], data, 28 );
139 GET_UINT32_LE( X[ 8], data, 32 );
140 GET_UINT32_LE( X[ 9], data, 36 );
141 GET_UINT32_LE( X[10], data, 40 );
142 GET_UINT32_LE( X[11], data, 44 );
143 GET_UINT32_LE( X[12], data, 48 );
144 GET_UINT32_LE( X[13], data, 52 );
145 GET_UINT32_LE( X[14], data, 56 );
146 GET_UINT32_LE( X[15], data, 60 );
147
148 A = Ap = ctx->state[0];
149 B = Bp = ctx->state[1];
150 C = Cp = ctx->state[2];
151 D = Dp = ctx->state[3];
152 E = Ep = ctx->state[4];
153
154#define F1( x, y, z ) ( x ^ y ^ z )
155#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
156#define F3( x, y, z ) ( ( x | ~y ) ^ z )
157#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
158#define F5( x, y, z ) ( x ^ ( y | ~z ) )
159
160#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
161
162#define P( a, b, c, d, e, r, s, f, k ) \
163 a += f( b, c, d ) + X[r] + k; \
164 a = S( a, s ) + e; \
165 c = S( c, 10 );
166
167#define P2( a, b, c, d, e, r, s, rp, sp ) \
168 P( a, b, c, d, e, r, s, F, K ); \
169 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
170
171#define F F1
172#define K 0x00000000
173#define Fp F5
174#define Kp 0x50A28BE6
175 P2( A, B, C, D, E, 0, 11, 5, 8 );
176 P2( E, A, B, C, D, 1, 14, 14, 9 );
177 P2( D, E, A, B, C, 2, 15, 7, 9 );
178 P2( C, D, E, A, B, 3, 12, 0, 11 );
179 P2( B, C, D, E, A, 4, 5, 9, 13 );
180 P2( A, B, C, D, E, 5, 8, 2, 15 );
181 P2( E, A, B, C, D, 6, 7, 11, 15 );
182 P2( D, E, A, B, C, 7, 9, 4, 5 );
183 P2( C, D, E, A, B, 8, 11, 13, 7 );
184 P2( B, C, D, E, A, 9, 13, 6, 7 );
185 P2( A, B, C, D, E, 10, 14, 15, 8 );
186 P2( E, A, B, C, D, 11, 15, 8, 11 );
187 P2( D, E, A, B, C, 12, 6, 1, 14 );
188 P2( C, D, E, A, B, 13, 7, 10, 14 );
189 P2( B, C, D, E, A, 14, 9, 3, 12 );
190 P2( A, B, C, D, E, 15, 8, 12, 6 );
191#undef F
192#undef K
193#undef Fp
194#undef Kp
195
196#define F F2
197#define K 0x5A827999
198#define Fp F4
199#define Kp 0x5C4DD124
200 P2( E, A, B, C, D, 7, 7, 6, 9 );
201 P2( D, E, A, B, C, 4, 6, 11, 13 );
202 P2( C, D, E, A, B, 13, 8, 3, 15 );
203 P2( B, C, D, E, A, 1, 13, 7, 7 );
204 P2( A, B, C, D, E, 10, 11, 0, 12 );
205 P2( E, A, B, C, D, 6, 9, 13, 8 );
206 P2( D, E, A, B, C, 15, 7, 5, 9 );
207 P2( C, D, E, A, B, 3, 15, 10, 11 );
208 P2( B, C, D, E, A, 12, 7, 14, 7 );
209 P2( A, B, C, D, E, 0, 12, 15, 7 );
210 P2( E, A, B, C, D, 9, 15, 8, 12 );
211 P2( D, E, A, B, C, 5, 9, 12, 7 );
212 P2( C, D, E, A, B, 2, 11, 4, 6 );
213 P2( B, C, D, E, A, 14, 7, 9, 15 );
214 P2( A, B, C, D, E, 11, 13, 1, 13 );
215 P2( E, A, B, C, D, 8, 12, 2, 11 );
216#undef F
217#undef K
218#undef Fp
219#undef Kp
220
221#define F F3
222#define K 0x6ED9EBA1
223#define Fp F3
224#define Kp 0x6D703EF3
225 P2( D, E, A, B, C, 3, 11, 15, 9 );
226 P2( C, D, E, A, B, 10, 13, 5, 7 );
227 P2( B, C, D, E, A, 14, 6, 1, 15 );
228 P2( A, B, C, D, E, 4, 7, 3, 11 );
229 P2( E, A, B, C, D, 9, 14, 7, 8 );
230 P2( D, E, A, B, C, 15, 9, 14, 6 );
231 P2( C, D, E, A, B, 8, 13, 6, 6 );
232 P2( B, C, D, E, A, 1, 15, 9, 14 );
233 P2( A, B, C, D, E, 2, 14, 11, 12 );
234 P2( E, A, B, C, D, 7, 8, 8, 13 );
235 P2( D, E, A, B, C, 0, 13, 12, 5 );
236 P2( C, D, E, A, B, 6, 6, 2, 14 );
237 P2( B, C, D, E, A, 13, 5, 10, 13 );
238 P2( A, B, C, D, E, 11, 12, 0, 13 );
239 P2( E, A, B, C, D, 5, 7, 4, 7 );
240 P2( D, E, A, B, C, 12, 5, 13, 5 );
241#undef F
242#undef K
243#undef Fp
244#undef Kp
245
246#define F F4
247#define K 0x8F1BBCDC
248#define Fp F2
249#define Kp 0x7A6D76E9
250 P2( C, D, E, A, B, 1, 11, 8, 15 );
251 P2( B, C, D, E, A, 9, 12, 6, 5 );
252 P2( A, B, C, D, E, 11, 14, 4, 8 );
253 P2( E, A, B, C, D, 10, 15, 1, 11 );
254 P2( D, E, A, B, C, 0, 14, 3, 14 );
255 P2( C, D, E, A, B, 8, 15, 11, 14 );
256 P2( B, C, D, E, A, 12, 9, 15, 6 );
257 P2( A, B, C, D, E, 4, 8, 0, 14 );
258 P2( E, A, B, C, D, 13, 9, 5, 6 );
259 P2( D, E, A, B, C, 3, 14, 12, 9 );
260 P2( C, D, E, A, B, 7, 5, 2, 12 );
261 P2( B, C, D, E, A, 15, 6, 13, 9 );
262 P2( A, B, C, D, E, 14, 8, 9, 12 );
263 P2( E, A, B, C, D, 5, 6, 7, 5 );
264 P2( D, E, A, B, C, 6, 5, 10, 15 );
265 P2( C, D, E, A, B, 2, 12, 14, 8 );
266#undef F
267#undef K
268#undef Fp
269#undef Kp
270
271#define F F5
272#define K 0xA953FD4E
273#define Fp F1
274#define Kp 0x00000000
275 P2( B, C, D, E, A, 4, 9, 12, 8 );
276 P2( A, B, C, D, E, 0, 15, 15, 5 );
277 P2( E, A, B, C, D, 5, 5, 10, 12 );
278 P2( D, E, A, B, C, 9, 11, 4, 9 );
279 P2( C, D, E, A, B, 7, 6, 1, 12 );
280 P2( B, C, D, E, A, 12, 8, 5, 5 );
281 P2( A, B, C, D, E, 2, 13, 8, 14 );
282 P2( E, A, B, C, D, 10, 12, 7, 6 );
283 P2( D, E, A, B, C, 14, 5, 6, 8 );
284 P2( C, D, E, A, B, 1, 12, 2, 13 );
285 P2( B, C, D, E, A, 3, 13, 13, 6 );
286 P2( A, B, C, D, E, 8, 14, 14, 5 );
287 P2( E, A, B, C, D, 11, 11, 0, 15 );
288 P2( D, E, A, B, C, 6, 8, 3, 13 );
289 P2( C, D, E, A, B, 15, 5, 9, 11 );
290 P2( B, C, D, E, A, 13, 6, 11, 11 );
291#undef F
292#undef K
293#undef Fp
294#undef Kp
295
296 C = ctx->state[1] + C + Dp;
297 ctx->state[1] = ctx->state[2] + D + Ep;
298 ctx->state[2] = ctx->state[3] + E + Ap;
299 ctx->state[3] = ctx->state[4] + A + Bp;
300 ctx->state[4] = ctx->state[0] + B + Cp;
301 ctx->state[0] = C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100302
303 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100304}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000305
306#if !defined(MBEDTLS_DEPRECATED_REMOVED)
307void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
308 const unsigned char data[64] )
309{
310 mbedtls_internal_ripemd160_process( ctx, data );
311}
312#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100314
315/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100316 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100317 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100318int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100319 const unsigned char *input,
320 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100321{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100322 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100323 size_t fill;
324 uint32_t left;
325
Brian White12895d12014-04-11 11:29:42 -0400326 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100327 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100328
329 left = ctx->total[0] & 0x3F;
330 fill = 64 - left;
331
332 ctx->total[0] += (uint32_t) ilen;
333 ctx->total[0] &= 0xFFFFFFFF;
334
335 if( ctx->total[0] < (uint32_t) ilen )
336 ctx->total[1]++;
337
338 if( left && ilen >= fill )
339 {
340 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100341
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100342 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100343 return( ret );
344
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100345 input += fill;
346 ilen -= fill;
347 left = 0;
348 }
349
350 while( ilen >= 64 )
351 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100352 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100353 return( ret );
354
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100355 input += 64;
356 ilen -= 64;
357 }
358
359 if( ilen > 0 )
360 {
361 memcpy( (void *) (ctx->buffer + left), input, ilen );
362 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100363
364 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100365}
366
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000367#if !defined(MBEDTLS_DEPRECATED_REMOVED)
368void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
369 const unsigned char *input,
370 size_t ilen )
371{
372 mbedtls_ripemd160_update_ret( ctx, input, ilen );
373}
374#endif
375
Paul Bakker61b699e2014-01-22 13:35:29 +0100376static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100377{
378 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
379 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
380 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
381 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
382};
383
384/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100385 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100386 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100387int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100388 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100389{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100390 int ret;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100391 uint32_t last, padn;
392 uint32_t high, low;
393 unsigned char msglen[8];
394
395 high = ( ctx->total[0] >> 29 )
396 | ( ctx->total[1] << 3 );
397 low = ( ctx->total[0] << 3 );
398
399 PUT_UINT32_LE( low, msglen, 0 );
400 PUT_UINT32_LE( high, msglen, 4 );
401
402 last = ctx->total[0] & 0x3F;
403 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
404
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100405 ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100406 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100407 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100408
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100409 ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100410 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100411 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100412
413 PUT_UINT32_LE( ctx->state[0], output, 0 );
414 PUT_UINT32_LE( ctx->state[1], output, 4 );
415 PUT_UINT32_LE( ctx->state[2], output, 8 );
416 PUT_UINT32_LE( ctx->state[3], output, 12 );
417 PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100418
419 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100420}
421
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000422#if !defined(MBEDTLS_DEPRECATED_REMOVED)
423void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
424 unsigned char output[20] )
425{
426 mbedtls_ripemd160_finish_ret( ctx, output );
427}
428#endif
429
Gilles Peskine342d9282018-01-23 18:21:21 +0100430#endif /* ! MBEDTLS_RIPEMD160_ALT */
431
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100432/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100433 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100434 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100435int mbedtls_ripemd160_ret( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100436 size_t ilen,
437 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100438{
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100439 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100443
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100444 if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100445 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100446
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100447 if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100448 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100449
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100450 if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100451 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100452
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100453exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100455
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100456 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100457}
458
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000459#if !defined(MBEDTLS_DEPRECATED_REMOVED)
460void mbedtls_ripemd160( const unsigned char *input,
461 size_t ilen,
462 unsigned char output[20] )
463{
464 mbedtls_ripemd160_ret( input, ilen, output );
465}
466#endif
467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100469/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100470 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100472 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100473#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100474static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100475{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100476 { "" },
477 { "a" },
478 { "abc" },
479 { "message digest" },
480 { "abcdefghijklmnopqrstuvwxyz" },
481 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
482 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
483 { "12345678901234567890123456789012345678901234567890123456789012"
484 "345678901234567890" },
485};
486
487static const size_t ripemd160_test_strlen[TESTS] =
488{
489 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100490};
491
Paul Bakker61b699e2014-01-22 13:35:29 +0100492static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100493{
494 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
495 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
496 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
497 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
498 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
499 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
500 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
501 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
502 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
503 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
504 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
505 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
506 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
507 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
508 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
509 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
510};
511
512/*
513 * Checkup routine
514 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100516{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100517 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100518 unsigned char output[20];
519
520 memset( output, 0, sizeof output );
521
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100522 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100523 {
524 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100526
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100527 ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100528 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100529 if( ret != 0 )
530 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100531
Paul Bakker61b699e2014-01-22 13:35:29 +0100532 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100533 {
534 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100535 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100536 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100537
538 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100540 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100541
Paul Bakker4400ecc2016-07-19 14:41:43 +0100542 if( verbose != 0 )
543 mbedtls_printf( "\n" );
544
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100545 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100546
547fail:
548 if( verbose != 0 )
549 mbedtls_printf( "failed\n" );
550
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100551 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100552}
553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556#endif /* MBEDTLS_RIPEMD160_C */