xref: /third_party/mbedtls/library/ripemd160.c (revision a8e1175b)
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
28void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
29{
30    memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
31}
32
33void 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
42void 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 */
51int 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 */
69int 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 */
266int 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
316static 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 */
327int 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
363exit:
364    mbedtls_ripemd160_free(ctx);
365    return ret;
366}
367
368#endif /* ! MBEDTLS_RIPEMD160_ALT */
369
370/*
371 * output = RIPEMD-160( input buffer )
372 */
373int 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
394exit:
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
406static 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
418static const size_t ripemd160_test_strlen[TESTS] =
419{
420    0, 1, 3, 14, 26, 56, 62, 80
421};
422
423static 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 */
446int 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
480fail:
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