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