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