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