xref: /reactos/dll/3rdparty/mbedtls/ripemd160.c (revision 7115d7ba)
1 /*
2  *  RIPE MD-160 implementation
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  *
7  *  This file is provided under the Apache License 2.0, or the
8  *  GNU General Public License v2.0 or later.
9  *
10  *  **********
11  *  Apache License 2.0:
12  *
13  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
14  *  not use this file except in compliance with the License.
15  *  You may obtain a copy of the License at
16  *
17  *  http://www.apache.org/licenses/LICENSE-2.0
18  *
19  *  Unless required by applicable law or agreed to in writing, software
20  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the License for the specific language governing permissions and
23  *  limitations under the License.
24  *
25  *  **********
26  *
27  *  **********
28  *  GNU General Public License v2.0 or later:
29  *
30  *  This program is free software; you can redistribute it and/or modify
31  *  it under the terms of the GNU General Public License as published by
32  *  the Free Software Foundation; either version 2 of the License, or
33  *  (at your option) any later version.
34  *
35  *  This program is distributed in the hope that it will be useful,
36  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
37  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  *  GNU General Public License for more details.
39  *
40  *  You should have received a copy of the GNU General Public License along
41  *  with this program; if not, write to the Free Software Foundation, Inc.,
42  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43  *
44  *  **********
45  *
46  *  This file is part of mbed TLS (https://tls.mbed.org)
47  */
48 
49 /*
50  *  The RIPEMD-160 algorithm was designed by RIPE in 1996
51  *  http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
52  *  http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
53  */
54 
55 #if !defined(MBEDTLS_CONFIG_FILE)
56 #include "mbedtls/config.h"
57 #else
58 #include MBEDTLS_CONFIG_FILE
59 #endif
60 
61 #if defined(MBEDTLS_RIPEMD160_C)
62 
63 #include "mbedtls/ripemd160.h"
64 
65 #include <string.h>
66 
67 #if defined(MBEDTLS_SELF_TEST)
68 #if defined(MBEDTLS_PLATFORM_C)
69 #include "mbedtls/platform.h"
70 #else
71 #include <stdio.h>
72 #define mbedtls_printf printf
73 #endif /* MBEDTLS_PLATFORM_C */
74 #endif /* MBEDTLS_SELF_TEST */
75 
76 #if !defined(MBEDTLS_RIPEMD160_ALT)
77 
78 /*
79  * 32-bit integer manipulation macros (little endian)
80  */
81 #ifndef GET_UINT32_LE
82 #define GET_UINT32_LE(n,b,i)                            \
83 {                                                       \
84     (n) = ( (uint32_t) (b)[(i)    ]       )             \
85         | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
86         | ( (uint32_t) (b)[(i) + 2] << 16 )             \
87         | ( (uint32_t) (b)[(i) + 3] << 24 );            \
88 }
89 #endif
90 
91 #ifndef PUT_UINT32_LE
92 #define PUT_UINT32_LE(n,b,i)                                    \
93 {                                                               \
94     (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
95     (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
96     (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
97     (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
98 }
99 #endif
100 
101 /* Implementation that should never be optimized out by the compiler */
102 static void mbedtls_zeroize( void *v, size_t n ) {
103     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
104 }
105 
106 void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
107 {
108     memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
109 }
110 
111 void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
112 {
113     if( ctx == NULL )
114         return;
115 
116     mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
117 }
118 
119 void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
120                         const mbedtls_ripemd160_context *src )
121 {
122     *dst = *src;
123 }
124 
125 /*
126  * RIPEMD-160 context setup
127  */
128 int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
129 {
130     ctx->total[0] = 0;
131     ctx->total[1] = 0;
132 
133     ctx->state[0] = 0x67452301;
134     ctx->state[1] = 0xEFCDAB89;
135     ctx->state[2] = 0x98BADCFE;
136     ctx->state[3] = 0x10325476;
137     ctx->state[4] = 0xC3D2E1F0;
138 
139     return( 0 );
140 }
141 
142 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
143 void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
144 {
145     mbedtls_ripemd160_starts_ret( ctx );
146 }
147 #endif
148 
149 #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
150 /*
151  * Process one block
152  */
153 int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
154                                         const unsigned char data[64] )
155 {
156     uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
157 
158     GET_UINT32_LE( X[ 0], data,  0 );
159     GET_UINT32_LE( X[ 1], data,  4 );
160     GET_UINT32_LE( X[ 2], data,  8 );
161     GET_UINT32_LE( X[ 3], data, 12 );
162     GET_UINT32_LE( X[ 4], data, 16 );
163     GET_UINT32_LE( X[ 5], data, 20 );
164     GET_UINT32_LE( X[ 6], data, 24 );
165     GET_UINT32_LE( X[ 7], data, 28 );
166     GET_UINT32_LE( X[ 8], data, 32 );
167     GET_UINT32_LE( X[ 9], data, 36 );
168     GET_UINT32_LE( X[10], data, 40 );
169     GET_UINT32_LE( X[11], data, 44 );
170     GET_UINT32_LE( X[12], data, 48 );
171     GET_UINT32_LE( X[13], data, 52 );
172     GET_UINT32_LE( X[14], data, 56 );
173     GET_UINT32_LE( X[15], data, 60 );
174 
175     A = Ap = ctx->state[0];
176     B = Bp = ctx->state[1];
177     C = Cp = ctx->state[2];
178     D = Dp = ctx->state[3];
179     E = Ep = ctx->state[4];
180 
181 #define F1( x, y, z )   ( x ^ y ^ z )
182 #define F2( x, y, z )   ( ( x & y ) | ( ~x & z ) )
183 #define F3( x, y, z )   ( ( x | ~y ) ^ z )
184 #define F4( x, y, z )   ( ( x & z ) | ( y & ~z ) )
185 #define F5( x, y, z )   ( x ^ ( y | ~z ) )
186 
187 #define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
188 
189 #define P( a, b, c, d, e, r, s, f, k )      \
190     a += f( b, c, d ) + X[r] + k;           \
191     a = S( a, s ) + e;                      \
192     c = S( c, 10 );
193 
194 #define P2( a, b, c, d, e, r, s, rp, sp )   \
195     P( a, b, c, d, e, r, s, F, K );         \
196     P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
197 
198 #define F   F1
199 #define K   0x00000000
200 #define Fp  F5
201 #define Kp  0x50A28BE6
202     P2( A, B, C, D, E,  0, 11,  5,  8 );
203     P2( E, A, B, C, D,  1, 14, 14,  9 );
204     P2( D, E, A, B, C,  2, 15,  7,  9 );
205     P2( C, D, E, A, B,  3, 12,  0, 11 );
206     P2( B, C, D, E, A,  4,  5,  9, 13 );
207     P2( A, B, C, D, E,  5,  8,  2, 15 );
208     P2( E, A, B, C, D,  6,  7, 11, 15 );
209     P2( D, E, A, B, C,  7,  9,  4,  5 );
210     P2( C, D, E, A, B,  8, 11, 13,  7 );
211     P2( B, C, D, E, A,  9, 13,  6,  7 );
212     P2( A, B, C, D, E, 10, 14, 15,  8 );
213     P2( E, A, B, C, D, 11, 15,  8, 11 );
214     P2( D, E, A, B, C, 12,  6,  1, 14 );
215     P2( C, D, E, A, B, 13,  7, 10, 14 );
216     P2( B, C, D, E, A, 14,  9,  3, 12 );
217     P2( A, B, C, D, E, 15,  8, 12,  6 );
218 #undef F
219 #undef K
220 #undef Fp
221 #undef Kp
222 
223 #define F   F2
224 #define K   0x5A827999
225 #define Fp  F4
226 #define Kp  0x5C4DD124
227     P2( E, A, B, C, D,  7,  7,  6,  9 );
228     P2( D, E, A, B, C,  4,  6, 11, 13 );
229     P2( C, D, E, A, B, 13,  8,  3, 15 );
230     P2( B, C, D, E, A,  1, 13,  7,  7 );
231     P2( A, B, C, D, E, 10, 11,  0, 12 );
232     P2( E, A, B, C, D,  6,  9, 13,  8 );
233     P2( D, E, A, B, C, 15,  7,  5,  9 );
234     P2( C, D, E, A, B,  3, 15, 10, 11 );
235     P2( B, C, D, E, A, 12,  7, 14,  7 );
236     P2( A, B, C, D, E,  0, 12, 15,  7 );
237     P2( E, A, B, C, D,  9, 15,  8, 12 );
238     P2( D, E, A, B, C,  5,  9, 12,  7 );
239     P2( C, D, E, A, B,  2, 11,  4,  6 );
240     P2( B, C, D, E, A, 14,  7,  9, 15 );
241     P2( A, B, C, D, E, 11, 13,  1, 13 );
242     P2( E, A, B, C, D,  8, 12,  2, 11 );
243 #undef F
244 #undef K
245 #undef Fp
246 #undef Kp
247 
248 #define F   F3
249 #define K   0x6ED9EBA1
250 #define Fp  F3
251 #define Kp  0x6D703EF3
252     P2( D, E, A, B, C,  3, 11, 15,  9 );
253     P2( C, D, E, A, B, 10, 13,  5,  7 );
254     P2( B, C, D, E, A, 14,  6,  1, 15 );
255     P2( A, B, C, D, E,  4,  7,  3, 11 );
256     P2( E, A, B, C, D,  9, 14,  7,  8 );
257     P2( D, E, A, B, C, 15,  9, 14,  6 );
258     P2( C, D, E, A, B,  8, 13,  6,  6 );
259     P2( B, C, D, E, A,  1, 15,  9, 14 );
260     P2( A, B, C, D, E,  2, 14, 11, 12 );
261     P2( E, A, B, C, D,  7,  8,  8, 13 );
262     P2( D, E, A, B, C,  0, 13, 12,  5 );
263     P2( C, D, E, A, B,  6,  6,  2, 14 );
264     P2( B, C, D, E, A, 13,  5, 10, 13 );
265     P2( A, B, C, D, E, 11, 12,  0, 13 );
266     P2( E, A, B, C, D,  5,  7,  4,  7 );
267     P2( D, E, A, B, C, 12,  5, 13,  5 );
268 #undef F
269 #undef K
270 #undef Fp
271 #undef Kp
272 
273 #define F   F4
274 #define K   0x8F1BBCDC
275 #define Fp  F2
276 #define Kp  0x7A6D76E9
277     P2( C, D, E, A, B,  1, 11,  8, 15 );
278     P2( B, C, D, E, A,  9, 12,  6,  5 );
279     P2( A, B, C, D, E, 11, 14,  4,  8 );
280     P2( E, A, B, C, D, 10, 15,  1, 11 );
281     P2( D, E, A, B, C,  0, 14,  3, 14 );
282     P2( C, D, E, A, B,  8, 15, 11, 14 );
283     P2( B, C, D, E, A, 12,  9, 15,  6 );
284     P2( A, B, C, D, E,  4,  8,  0, 14 );
285     P2( E, A, B, C, D, 13,  9,  5,  6 );
286     P2( D, E, A, B, C,  3, 14, 12,  9 );
287     P2( C, D, E, A, B,  7,  5,  2, 12 );
288     P2( B, C, D, E, A, 15,  6, 13,  9 );
289     P2( A, B, C, D, E, 14,  8,  9, 12 );
290     P2( E, A, B, C, D,  5,  6,  7,  5 );
291     P2( D, E, A, B, C,  6,  5, 10, 15 );
292     P2( C, D, E, A, B,  2, 12, 14,  8 );
293 #undef F
294 #undef K
295 #undef Fp
296 #undef Kp
297 
298 #define F   F5
299 #define K   0xA953FD4E
300 #define Fp  F1
301 #define Kp  0x00000000
302     P2( B, C, D, E, A,  4,  9, 12,  8 );
303     P2( A, B, C, D, E,  0, 15, 15,  5 );
304     P2( E, A, B, C, D,  5,  5, 10, 12 );
305     P2( D, E, A, B, C,  9, 11,  4,  9 );
306     P2( C, D, E, A, B,  7,  6,  1, 12 );
307     P2( B, C, D, E, A, 12,  8,  5,  5 );
308     P2( A, B, C, D, E,  2, 13,  8, 14 );
309     P2( E, A, B, C, D, 10, 12,  7,  6 );
310     P2( D, E, A, B, C, 14,  5,  6,  8 );
311     P2( C, D, E, A, B,  1, 12,  2, 13 );
312     P2( B, C, D, E, A,  3, 13, 13,  6 );
313     P2( A, B, C, D, E,  8, 14, 14,  5 );
314     P2( E, A, B, C, D, 11, 11,  0, 15 );
315     P2( D, E, A, B, C,  6,  8,  3, 13 );
316     P2( C, D, E, A, B, 15,  5,  9, 11 );
317     P2( B, C, D, E, A, 13,  6, 11, 11 );
318 #undef F
319 #undef K
320 #undef Fp
321 #undef Kp
322 
323     C             = ctx->state[1] + C + Dp;
324     ctx->state[1] = ctx->state[2] + D + Ep;
325     ctx->state[2] = ctx->state[3] + E + Ap;
326     ctx->state[3] = ctx->state[4] + A + Bp;
327     ctx->state[4] = ctx->state[0] + B + Cp;
328     ctx->state[0] = C;
329 
330     return( 0 );
331 }
332 
333 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
334 void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
335                                 const unsigned char data[64] )
336 {
337     mbedtls_internal_ripemd160_process( ctx, data );
338 }
339 #endif
340 #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
341 
342 /*
343  * RIPEMD-160 process buffer
344  */
345 int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
346                                   const unsigned char *input,
347                                   size_t ilen )
348 {
349     int ret;
350     size_t fill;
351     uint32_t left;
352 
353     if( ilen == 0 )
354         return( 0 );
355 
356     left = ctx->total[0] & 0x3F;
357     fill = 64 - left;
358 
359     ctx->total[0] += (uint32_t) ilen;
360     ctx->total[0] &= 0xFFFFFFFF;
361 
362     if( ctx->total[0] < (uint32_t) ilen )
363         ctx->total[1]++;
364 
365     if( left && ilen >= fill )
366     {
367         memcpy( (void *) (ctx->buffer + left), input, fill );
368 
369         if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
370             return( ret );
371 
372         input += fill;
373         ilen  -= fill;
374         left = 0;
375     }
376 
377     while( ilen >= 64 )
378     {
379         if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
380             return( ret );
381 
382         input += 64;
383         ilen  -= 64;
384     }
385 
386     if( ilen > 0 )
387     {
388         memcpy( (void *) (ctx->buffer + left), input, ilen );
389     }
390 
391     return( 0 );
392 }
393 
394 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
395 void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
396                                const unsigned char *input,
397                                size_t ilen )
398 {
399     mbedtls_ripemd160_update_ret( ctx, input, ilen );
400 }
401 #endif
402 
403 static const unsigned char ripemd160_padding[64] =
404 {
405  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
406     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
407     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
408     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
409 };
410 
411 /*
412  * RIPEMD-160 final digest
413  */
414 int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
415                                   unsigned char output[20] )
416 {
417     int ret;
418     uint32_t last, padn;
419     uint32_t high, low;
420     unsigned char msglen[8];
421 
422     high = ( ctx->total[0] >> 29 )
423          | ( ctx->total[1] <<  3 );
424     low  = ( ctx->total[0] <<  3 );
425 
426     PUT_UINT32_LE( low,  msglen, 0 );
427     PUT_UINT32_LE( high, msglen, 4 );
428 
429     last = ctx->total[0] & 0x3F;
430     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
431 
432     ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
433     if( ret != 0 )
434         return( ret );
435 
436     ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
437     if( ret != 0 )
438         return( ret );
439 
440     PUT_UINT32_LE( ctx->state[0], output,  0 );
441     PUT_UINT32_LE( ctx->state[1], output,  4 );
442     PUT_UINT32_LE( ctx->state[2], output,  8 );
443     PUT_UINT32_LE( ctx->state[3], output, 12 );
444     PUT_UINT32_LE( ctx->state[4], output, 16 );
445 
446     return( 0 );
447 }
448 
449 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
450 void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
451                                unsigned char output[20] )
452 {
453     mbedtls_ripemd160_finish_ret( ctx, output );
454 }
455 #endif
456 
457 #endif /* ! MBEDTLS_RIPEMD160_ALT */
458 
459 /*
460  * output = RIPEMD-160( input buffer )
461  */
462 int mbedtls_ripemd160_ret( const unsigned char *input,
463                            size_t ilen,
464                            unsigned char output[20] )
465 {
466     int ret;
467     mbedtls_ripemd160_context ctx;
468 
469     mbedtls_ripemd160_init( &ctx );
470 
471     if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
472         goto exit;
473 
474     if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
475         goto exit;
476 
477     if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
478         goto exit;
479 
480 exit:
481     mbedtls_ripemd160_free( &ctx );
482 
483     return( ret );
484 }
485 
486 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
487 void mbedtls_ripemd160( const unsigned char *input,
488                         size_t ilen,
489                         unsigned char output[20] )
490 {
491     mbedtls_ripemd160_ret( input, ilen, output );
492 }
493 #endif
494 
495 #if defined(MBEDTLS_SELF_TEST)
496 /*
497  * Test vectors from the RIPEMD-160 paper and
498  * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
499  */
500 #define TESTS   8
501 static const unsigned char ripemd160_test_str[TESTS][81] =
502 {
503     { "" },
504     { "a" },
505     { "abc" },
506     { "message digest" },
507     { "abcdefghijklmnopqrstuvwxyz" },
508     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
509     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
510     { "12345678901234567890123456789012345678901234567890123456789012"
511       "345678901234567890" },
512 };
513 
514 static const size_t ripemd160_test_strlen[TESTS] =
515 {
516     0, 1, 3, 14, 26, 56, 62, 80
517 };
518 
519 static const unsigned char ripemd160_test_md[TESTS][20] =
520 {
521     { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
522       0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
523     { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
524       0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
525     { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
526       0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
527     { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
528       0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
529     { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
530       0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
531     { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
532       0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
533     { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
534       0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
535     { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
536       0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
537 };
538 
539 /*
540  * Checkup routine
541  */
542 int mbedtls_ripemd160_self_test( int verbose )
543 {
544     int i, ret = 0;
545     unsigned char output[20];
546 
547     memset( output, 0, sizeof output );
548 
549     for( i = 0; i < TESTS; i++ )
550     {
551         if( verbose != 0 )
552             mbedtls_printf( "  RIPEMD-160 test #%d: ", i + 1 );
553 
554         ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
555                                      ripemd160_test_strlen[i], output );
556         if( ret != 0 )
557             goto fail;
558 
559         if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
560         {
561             ret = 1;
562             goto fail;
563         }
564 
565         if( verbose != 0 )
566             mbedtls_printf( "passed\n" );
567     }
568 
569     if( verbose != 0 )
570         mbedtls_printf( "\n" );
571 
572     return( 0 );
573 
574 fail:
575     if( verbose != 0 )
576         mbedtls_printf( "failed\n" );
577 
578     return( ret );
579 }
580 
581 #endif /* MBEDTLS_SELF_TEST */
582 
583 #endif /* MBEDTLS_RIPEMD160_C */
584