1 /*
2 * RIPE MD-160 implementation
3 *
4 * Copyright The Mbed TLS Contributors
5 * 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.
18 */
19
20 /*
21 * The RIPEMD-160 algorithm was designed by RIPE in 1996
22 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
23 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
24 */
25
26 #include "common.h"
27
28 #if defined(MBEDTLS_RIPEMD160_C)
29
30 #include "mbedtls/ripemd160.h"
31 #include "mbedtls/platform_util.h"
32 #include "mbedtls/error.h"
33
34 #include <string.h>
35
36 #if defined(MBEDTLS_SELF_TEST)
37 #if defined(MBEDTLS_PLATFORM_C)
38 #include "mbedtls/platform.h"
39 #else
40 #include <stdio.h>
41 #define mbedtls_printf printf
42 #endif /* MBEDTLS_PLATFORM_C */
43 #endif /* MBEDTLS_SELF_TEST */
44
45 #if !defined(MBEDTLS_RIPEMD160_ALT)
46
mbedtls_ripemd160_init(mbedtls_ripemd160_context * ctx)47 void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
48 {
49 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
50 }
51
mbedtls_ripemd160_free(mbedtls_ripemd160_context * ctx)52 void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
53 {
54 if( ctx == NULL )
55 return;
56
57 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
58 }
59
mbedtls_ripemd160_clone(mbedtls_ripemd160_context * dst,const mbedtls_ripemd160_context * src)60 void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
61 const mbedtls_ripemd160_context *src )
62 {
63 *dst = *src;
64 }
65
66 /*
67 * RIPEMD-160 context setup
68 */
mbedtls_ripemd160_starts(mbedtls_ripemd160_context * ctx)69 int mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
70 {
71 ctx->total[0] = 0;
72 ctx->total[1] = 0;
73
74 ctx->state[0] = 0x67452301;
75 ctx->state[1] = 0xEFCDAB89;
76 ctx->state[2] = 0x98BADCFE;
77 ctx->state[3] = 0x10325476;
78 ctx->state[4] = 0xC3D2E1F0;
79
80 return( 0 );
81 }
82
83 #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
84 /*
85 * Process one block
86 */
mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context * ctx,const unsigned char data[64])87 int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
88 const unsigned char data[64] )
89 {
90 struct
91 {
92 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
93 } local;
94
95 local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
96 local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
97 local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
98 local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
99 local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
100 local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
101 local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
102 local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
103 local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
104 local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
105 local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
106 local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
107 local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
108 local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
109 local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
110 local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
111
112 local.A = local.Ap = ctx->state[0];
113 local.B = local.Bp = ctx->state[1];
114 local.C = local.Cp = ctx->state[2];
115 local.D = local.Dp = ctx->state[3];
116 local.E = local.Ep = ctx->state[4];
117
118 #define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
119 #define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
120 #define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
121 #define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
122 #define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
123
124 #define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
125
126 #define P( a, b, c, d, e, r, s, f, k ) \
127 do \
128 { \
129 (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
130 (a) = S( (a), (s) ) + (e); \
131 (c) = S( (c), 10 ); \
132 } while( 0 )
133
134 #define P2( a, b, c, d, e, r, s, rp, sp ) \
135 do \
136 { \
137 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
138 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
139 (rp), (sp), Fp, Kp ); \
140 } while( 0 )
141
142 #define F F1
143 #define K 0x00000000
144 #define Fp F5
145 #define Kp 0x50A28BE6
146 P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
147 P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
148 P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
149 P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
150 P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
151 P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
152 P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
153 P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
154 P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
155 P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
156 P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
157 P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
158 P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
159 P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
160 P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
161 P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
162 #undef F
163 #undef K
164 #undef Fp
165 #undef Kp
166
167 #define F F2
168 #define K 0x5A827999
169 #define Fp F4
170 #define Kp 0x5C4DD124
171 P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
172 P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
173 P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
174 P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
175 P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
176 P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
177 P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
178 P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
179 P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
180 P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
181 P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
182 P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
183 P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
184 P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
185 P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
186 P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
187 #undef F
188 #undef K
189 #undef Fp
190 #undef Kp
191
192 #define F F3
193 #define K 0x6ED9EBA1
194 #define Fp F3
195 #define Kp 0x6D703EF3
196 P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
197 P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
198 P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
199 P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
200 P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
201 P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
202 P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
203 P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
204 P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
205 P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
206 P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
207 P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
208 P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
209 P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
210 P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
211 P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
212 #undef F
213 #undef K
214 #undef Fp
215 #undef Kp
216
217 #define F F4
218 #define K 0x8F1BBCDC
219 #define Fp F2
220 #define Kp 0x7A6D76E9
221 P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
222 P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
223 P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
224 P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
225 P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
226 P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
227 P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
228 P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
229 P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
230 P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
231 P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
232 P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
233 P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
234 P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
235 P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
236 P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
237 #undef F
238 #undef K
239 #undef Fp
240 #undef Kp
241
242 #define F F5
243 #define K 0xA953FD4E
244 #define Fp F1
245 #define Kp 0x00000000
246 P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
247 P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
248 P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
249 P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
250 P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
251 P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
252 P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
253 P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
254 P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
255 P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
256 P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
257 P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
258 P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
259 P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
260 P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
261 P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
262 #undef F
263 #undef K
264 #undef Fp
265 #undef Kp
266
267 local.C = ctx->state[1] + local.C + local.Dp;
268 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
269 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
270 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
271 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
272 ctx->state[0] = local.C;
273
274 /* Zeroise variables to clear sensitive data from memory. */
275 mbedtls_platform_zeroize( &local, sizeof( local ) );
276
277 return( 0 );
278 }
279
280 #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
281
282 /*
283 * RIPEMD-160 process buffer
284 */
mbedtls_ripemd160_update(mbedtls_ripemd160_context * ctx,const unsigned char * input,size_t ilen)285 int mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
286 const unsigned char *input,
287 size_t ilen )
288 {
289 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
290 size_t fill;
291 uint32_t left;
292
293 if( ilen == 0 )
294 return( 0 );
295
296 left = ctx->total[0] & 0x3F;
297 fill = 64 - left;
298
299 ctx->total[0] += (uint32_t) ilen;
300 ctx->total[0] &= 0xFFFFFFFF;
301
302 if( ctx->total[0] < (uint32_t) ilen )
303 ctx->total[1]++;
304
305 if( left && ilen >= fill )
306 {
307 memcpy( (void *) (ctx->buffer + left), input, fill );
308
309 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
310 return( ret );
311
312 input += fill;
313 ilen -= fill;
314 left = 0;
315 }
316
317 while( ilen >= 64 )
318 {
319 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
320 return( ret );
321
322 input += 64;
323 ilen -= 64;
324 }
325
326 if( ilen > 0 )
327 {
328 memcpy( (void *) (ctx->buffer + left), input, ilen );
329 }
330
331 return( 0 );
332 }
333
334 static const unsigned char ripemd160_padding[64] =
335 {
336 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
339 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
340 };
341
342 /*
343 * RIPEMD-160 final digest
344 */
mbedtls_ripemd160_finish(mbedtls_ripemd160_context * ctx,unsigned char output[20])345 int mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
346 unsigned char output[20] )
347 {
348 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
349 uint32_t last, padn;
350 uint32_t high, low;
351 unsigned char msglen[8];
352
353 high = ( ctx->total[0] >> 29 )
354 | ( ctx->total[1] << 3 );
355 low = ( ctx->total[0] << 3 );
356
357 MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
358 MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
359
360 last = ctx->total[0] & 0x3F;
361 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
362
363 ret = mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
364 if( ret != 0 )
365 return( ret );
366
367 ret = mbedtls_ripemd160_update( ctx, msglen, 8 );
368 if( ret != 0 )
369 return( ret );
370
371 MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
372 MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
373 MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
374 MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
375 MBEDTLS_PUT_UINT32_LE( ctx->state[4], output, 16 );
376
377 return( 0 );
378 }
379
380 #endif /* ! MBEDTLS_RIPEMD160_ALT */
381
382 /*
383 * output = RIPEMD-160( input buffer )
384 */
mbedtls_ripemd160(const unsigned char * input,size_t ilen,unsigned char output[20])385 int mbedtls_ripemd160( const unsigned char *input,
386 size_t ilen,
387 unsigned char output[20] )
388 {
389 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
390 mbedtls_ripemd160_context ctx;
391
392 mbedtls_ripemd160_init( &ctx );
393
394 if( ( ret = mbedtls_ripemd160_starts( &ctx ) ) != 0 )
395 goto exit;
396
397 if( ( ret = mbedtls_ripemd160_update( &ctx, input, ilen ) ) != 0 )
398 goto exit;
399
400 if( ( ret = mbedtls_ripemd160_finish( &ctx, output ) ) != 0 )
401 goto exit;
402
403 exit:
404 mbedtls_ripemd160_free( &ctx );
405
406 return( ret );
407 }
408
409 #if defined(MBEDTLS_SELF_TEST)
410 /*
411 * Test vectors from the RIPEMD-160 paper and
412 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
413 */
414 #define TESTS 8
415 static const unsigned char ripemd160_test_str[TESTS][81] =
416 {
417 { "" },
418 { "a" },
419 { "abc" },
420 { "message digest" },
421 { "abcdefghijklmnopqrstuvwxyz" },
422 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
423 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
424 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
425 };
426
427 static const size_t ripemd160_test_strlen[TESTS] =
428 {
429 0, 1, 3, 14, 26, 56, 62, 80
430 };
431
432 static const unsigned char ripemd160_test_md[TESTS][20] =
433 {
434 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
435 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
436 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
437 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
438 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
439 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
440 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
441 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
442 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
443 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
444 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
445 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
446 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
447 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
448 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
449 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
450 };
451
452 /*
453 * Checkup routine
454 */
mbedtls_ripemd160_self_test(int verbose)455 int mbedtls_ripemd160_self_test( int verbose )
456 {
457 int i, ret = 0;
458 unsigned char output[20];
459
460 memset( output, 0, sizeof output );
461
462 for( i = 0; i < TESTS; i++ )
463 {
464 if( verbose != 0 )
465 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
466
467 ret = mbedtls_ripemd160( ripemd160_test_str[i],
468 ripemd160_test_strlen[i], output );
469 if( ret != 0 )
470 goto fail;
471
472 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
473 {
474 ret = 1;
475 goto fail;
476 }
477
478 if( verbose != 0 )
479 mbedtls_printf( "passed\n" );
480 }
481
482 if( verbose != 0 )
483 mbedtls_printf( "\n" );
484
485 return( 0 );
486
487 fail:
488 if( verbose != 0 )
489 mbedtls_printf( "failed\n" );
490
491 return( ret );
492 }
493
494 #endif /* MBEDTLS_SELF_TEST */
495
496 #endif /* MBEDTLS_RIPEMD160_C */
497