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