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