• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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