1817466cbSJens Wiklander /*
2817466cbSJens Wiklander * RIPE MD-160 implementation
3817466cbSJens Wiklander *
47901324dSJerome Forissier * Copyright The Mbed TLS Contributors
5*b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6817466cbSJens Wiklander */
7817466cbSJens Wiklander
8817466cbSJens Wiklander /*
9817466cbSJens Wiklander * The RIPEMD-160 algorithm was designed by RIPE in 1996
10817466cbSJens Wiklander * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
11817466cbSJens Wiklander * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
12817466cbSJens Wiklander */
13817466cbSJens Wiklander
147901324dSJerome Forissier #include "common.h"
15817466cbSJens Wiklander
16817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C)
17817466cbSJens Wiklander
18817466cbSJens Wiklander #include "mbedtls/ripemd160.h"
193d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
2011fa71b9SJerome Forissier #include "mbedtls/error.h"
21817466cbSJens Wiklander
22817466cbSJens Wiklander #include <string.h>
23817466cbSJens Wiklander
24817466cbSJens Wiklander #include "mbedtls/platform.h"
25817466cbSJens Wiklander
263d3b0591SJens Wiklander #if !defined(MBEDTLS_RIPEMD160_ALT)
273d3b0591SJens Wiklander
mbedtls_ripemd160_init(mbedtls_ripemd160_context * ctx)28817466cbSJens Wiklander void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
29817466cbSJens Wiklander {
30817466cbSJens Wiklander memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
31817466cbSJens Wiklander }
32817466cbSJens Wiklander
mbedtls_ripemd160_free(mbedtls_ripemd160_context * ctx)33817466cbSJens Wiklander void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
34817466cbSJens Wiklander {
3532b31808SJens Wiklander if (ctx == NULL) {
36817466cbSJens Wiklander return;
3732b31808SJens Wiklander }
38817466cbSJens Wiklander
393d3b0591SJens Wiklander mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
40817466cbSJens Wiklander }
41817466cbSJens Wiklander
mbedtls_ripemd160_clone(mbedtls_ripemd160_context * dst,const mbedtls_ripemd160_context * src)42817466cbSJens Wiklander void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
43817466cbSJens Wiklander const mbedtls_ripemd160_context *src)
44817466cbSJens Wiklander {
45817466cbSJens Wiklander *dst = *src;
46817466cbSJens Wiklander }
47817466cbSJens Wiklander
48817466cbSJens Wiklander /*
49817466cbSJens Wiklander * RIPEMD-160 context setup
50817466cbSJens Wiklander */
mbedtls_ripemd160_starts(mbedtls_ripemd160_context * ctx)5132b31808SJens Wiklander int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx)
52817466cbSJens Wiklander {
53817466cbSJens Wiklander ctx->total[0] = 0;
54817466cbSJens Wiklander ctx->total[1] = 0;
55817466cbSJens Wiklander
56817466cbSJens Wiklander ctx->state[0] = 0x67452301;
57817466cbSJens Wiklander ctx->state[1] = 0xEFCDAB89;
58817466cbSJens Wiklander ctx->state[2] = 0x98BADCFE;
59817466cbSJens Wiklander ctx->state[3] = 0x10325476;
60817466cbSJens Wiklander ctx->state[4] = 0xC3D2E1F0;
613d3b0591SJens Wiklander
6232b31808SJens Wiklander return 0;
63817466cbSJens Wiklander }
64817466cbSJens Wiklander
65817466cbSJens Wiklander #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
66817466cbSJens Wiklander /*
67817466cbSJens Wiklander * Process one block
68817466cbSJens Wiklander */
mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context * ctx,const unsigned char data[64])693d3b0591SJens Wiklander int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
703d3b0591SJens Wiklander const unsigned char data[64])
71817466cbSJens Wiklander {
7232b31808SJens Wiklander struct {
73817466cbSJens Wiklander uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
747901324dSJerome Forissier } local;
75817466cbSJens Wiklander
76039e02dfSJerome Forissier local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0);
77039e02dfSJerome Forissier local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4);
78039e02dfSJerome Forissier local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8);
79039e02dfSJerome Forissier local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12);
80039e02dfSJerome Forissier local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16);
81039e02dfSJerome Forissier local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20);
82039e02dfSJerome Forissier local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24);
83039e02dfSJerome Forissier local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28);
84039e02dfSJerome Forissier local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32);
85039e02dfSJerome Forissier local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36);
86039e02dfSJerome Forissier local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40);
87039e02dfSJerome Forissier local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44);
88039e02dfSJerome Forissier local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48);
89039e02dfSJerome Forissier local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52);
90039e02dfSJerome Forissier local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56);
91039e02dfSJerome Forissier local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60);
92817466cbSJens Wiklander
937901324dSJerome Forissier local.A = local.Ap = ctx->state[0];
947901324dSJerome Forissier local.B = local.Bp = ctx->state[1];
957901324dSJerome Forissier local.C = local.Cp = ctx->state[2];
967901324dSJerome Forissier local.D = local.Dp = ctx->state[3];
977901324dSJerome Forissier local.E = local.Ep = ctx->state[4];
98817466cbSJens Wiklander
995b25c76aSJerome Forissier #define F1(x, y, z) ((x) ^ (y) ^ (z))
1005b25c76aSJerome Forissier #define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
1015b25c76aSJerome Forissier #define F3(x, y, z) (((x) | ~(y)) ^ (z))
1025b25c76aSJerome Forissier #define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
1035b25c76aSJerome Forissier #define F5(x, y, z) ((x) ^ ((y) | ~(z)))
104817466cbSJens Wiklander
1055b25c76aSJerome Forissier #define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
106817466cbSJens Wiklander
107817466cbSJens Wiklander #define P(a, b, c, d, e, r, s, f, k) \
1085b25c76aSJerome Forissier do \
1095b25c76aSJerome Forissier { \
1107901324dSJerome Forissier (a) += f((b), (c), (d)) + local.X[r] + (k); \
1115b25c76aSJerome Forissier (a) = S((a), (s)) + (e); \
1125b25c76aSJerome Forissier (c) = S((c), 10); \
1135b25c76aSJerome Forissier } while (0)
114817466cbSJens Wiklander
115817466cbSJens Wiklander #define P2(a, b, c, d, e, r, s, rp, sp) \
1165b25c76aSJerome Forissier do \
1175b25c76aSJerome Forissier { \
1185b25c76aSJerome Forissier P((a), (b), (c), (d), (e), (r), (s), F, K); \
1195b25c76aSJerome Forissier P(a ## p, b ## p, c ## p, d ## p, e ## p, \
1205b25c76aSJerome Forissier (rp), (sp), Fp, Kp); \
1215b25c76aSJerome Forissier } while (0)
122817466cbSJens Wiklander
123817466cbSJens Wiklander #define F F1
124817466cbSJens Wiklander #define K 0x00000000
125817466cbSJens Wiklander #define Fp F5
126817466cbSJens Wiklander #define Kp 0x50A28BE6
1277901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8);
1287901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9);
1297901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9);
1307901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11);
1317901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13);
1327901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15);
1337901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15);
1347901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5);
1357901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7);
1367901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7);
1377901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8);
1387901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11);
1397901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14);
1407901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14);
1417901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12);
1427901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6);
143817466cbSJens Wiklander #undef F
144817466cbSJens Wiklander #undef K
145817466cbSJens Wiklander #undef Fp
146817466cbSJens Wiklander #undef Kp
147817466cbSJens Wiklander
148817466cbSJens Wiklander #define F F2
149817466cbSJens Wiklander #define K 0x5A827999
150817466cbSJens Wiklander #define Fp F4
151817466cbSJens Wiklander #define Kp 0x5C4DD124
1527901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9);
1537901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13);
1547901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15);
1557901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7);
1567901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12);
1577901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8);
1587901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9);
1597901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11);
1607901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7);
1617901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7);
1627901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12);
1637901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7);
1647901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6);
1657901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15);
1667901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13);
1677901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11);
168817466cbSJens Wiklander #undef F
169817466cbSJens Wiklander #undef K
170817466cbSJens Wiklander #undef Fp
171817466cbSJens Wiklander #undef Kp
172817466cbSJens Wiklander
173817466cbSJens Wiklander #define F F3
174817466cbSJens Wiklander #define K 0x6ED9EBA1
175817466cbSJens Wiklander #define Fp F3
176817466cbSJens Wiklander #define Kp 0x6D703EF3
1777901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9);
1787901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7);
1797901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15);
1807901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11);
1817901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8);
1827901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6);
1837901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6);
1847901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14);
1857901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12);
1867901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13);
1877901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5);
1887901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14);
1897901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13);
1907901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13);
1917901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7);
1927901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5);
193817466cbSJens Wiklander #undef F
194817466cbSJens Wiklander #undef K
195817466cbSJens Wiklander #undef Fp
196817466cbSJens Wiklander #undef Kp
197817466cbSJens Wiklander
198817466cbSJens Wiklander #define F F4
199817466cbSJens Wiklander #define K 0x8F1BBCDC
200817466cbSJens Wiklander #define Fp F2
201817466cbSJens Wiklander #define Kp 0x7A6D76E9
2027901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15);
2037901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5);
2047901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8);
2057901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11);
2067901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14);
2077901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14);
2087901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6);
2097901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14);
2107901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6);
2117901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9);
2127901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12);
2137901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9);
2147901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12);
2157901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5);
2167901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15);
2177901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8);
218817466cbSJens Wiklander #undef F
219817466cbSJens Wiklander #undef K
220817466cbSJens Wiklander #undef Fp
221817466cbSJens Wiklander #undef Kp
222817466cbSJens Wiklander
223817466cbSJens Wiklander #define F F5
224817466cbSJens Wiklander #define K 0xA953FD4E
225817466cbSJens Wiklander #define Fp F1
226817466cbSJens Wiklander #define Kp 0x00000000
2277901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8);
2287901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5);
2297901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12);
2307901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9);
2317901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12);
2327901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5);
2337901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14);
2347901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6);
2357901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8);
2367901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13);
2377901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6);
2387901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5);
2397901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15);
2407901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13);
2417901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11);
2427901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11);
243817466cbSJens Wiklander #undef F
244817466cbSJens Wiklander #undef K
245817466cbSJens Wiklander #undef Fp
246817466cbSJens Wiklander #undef Kp
247817466cbSJens Wiklander
2487901324dSJerome Forissier local.C = ctx->state[1] + local.C + local.Dp;
2497901324dSJerome Forissier ctx->state[1] = ctx->state[2] + local.D + local.Ep;
2507901324dSJerome Forissier ctx->state[2] = ctx->state[3] + local.E + local.Ap;
2517901324dSJerome Forissier ctx->state[3] = ctx->state[4] + local.A + local.Bp;
2527901324dSJerome Forissier ctx->state[4] = ctx->state[0] + local.B + local.Cp;
2537901324dSJerome Forissier ctx->state[0] = local.C;
2547901324dSJerome Forissier
2557901324dSJerome Forissier /* Zeroise variables to clear sensitive data from memory. */
2567901324dSJerome Forissier mbedtls_platform_zeroize(&local, sizeof(local));
2573d3b0591SJens Wiklander
25832b31808SJens Wiklander return 0;
259817466cbSJens Wiklander }
2603d3b0591SJens Wiklander
261817466cbSJens Wiklander #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
262817466cbSJens Wiklander
263817466cbSJens Wiklander /*
264817466cbSJens Wiklander * RIPEMD-160 process buffer
265817466cbSJens Wiklander */
mbedtls_ripemd160_update(mbedtls_ripemd160_context * ctx,const unsigned char * input,size_t ilen)26632b31808SJens Wiklander int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
2673d3b0591SJens Wiklander const unsigned char *input,
2683d3b0591SJens Wiklander size_t ilen)
269817466cbSJens Wiklander {
27011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
271817466cbSJens Wiklander size_t fill;
272817466cbSJens Wiklander uint32_t left;
273817466cbSJens Wiklander
27432b31808SJens Wiklander if (ilen == 0) {
27532b31808SJens Wiklander return 0;
27632b31808SJens Wiklander }
277817466cbSJens Wiklander
278817466cbSJens Wiklander left = ctx->total[0] & 0x3F;
279817466cbSJens Wiklander fill = 64 - left;
280817466cbSJens Wiklander
281817466cbSJens Wiklander ctx->total[0] += (uint32_t) ilen;
282817466cbSJens Wiklander ctx->total[0] &= 0xFFFFFFFF;
283817466cbSJens Wiklander
28432b31808SJens Wiklander if (ctx->total[0] < (uint32_t) ilen) {
285817466cbSJens Wiklander ctx->total[1]++;
28632b31808SJens Wiklander }
287817466cbSJens Wiklander
28832b31808SJens Wiklander if (left && ilen >= fill) {
289817466cbSJens Wiklander memcpy((void *) (ctx->buffer + left), input, fill);
2903d3b0591SJens Wiklander
29132b31808SJens Wiklander if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
29232b31808SJens Wiklander return ret;
29332b31808SJens Wiklander }
2943d3b0591SJens Wiklander
295817466cbSJens Wiklander input += fill;
296817466cbSJens Wiklander ilen -= fill;
297817466cbSJens Wiklander left = 0;
298817466cbSJens Wiklander }
299817466cbSJens Wiklander
30032b31808SJens Wiklander while (ilen >= 64) {
30132b31808SJens Wiklander if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
30232b31808SJens Wiklander return ret;
30332b31808SJens Wiklander }
3043d3b0591SJens Wiklander
305817466cbSJens Wiklander input += 64;
306817466cbSJens Wiklander ilen -= 64;
307817466cbSJens Wiklander }
308817466cbSJens Wiklander
30932b31808SJens Wiklander if (ilen > 0) {
310817466cbSJens Wiklander memcpy((void *) (ctx->buffer + left), input, ilen);
311817466cbSJens Wiklander }
3123d3b0591SJens Wiklander
31332b31808SJens Wiklander return 0;
314817466cbSJens Wiklander }
315817466cbSJens Wiklander
316817466cbSJens Wiklander static const unsigned char ripemd160_padding[64] =
317817466cbSJens Wiklander {
318817466cbSJens Wiklander 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
319817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
322817466cbSJens Wiklander };
323817466cbSJens Wiklander
324817466cbSJens Wiklander /*
325817466cbSJens Wiklander * RIPEMD-160 final digest
326817466cbSJens Wiklander */
mbedtls_ripemd160_finish(mbedtls_ripemd160_context * ctx,unsigned char output[20])32732b31808SJens Wiklander int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
3283d3b0591SJens Wiklander unsigned char output[20])
329817466cbSJens Wiklander {
33011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
331817466cbSJens Wiklander uint32_t last, padn;
332817466cbSJens Wiklander uint32_t high, low;
333817466cbSJens Wiklander unsigned char msglen[8];
334817466cbSJens Wiklander
335817466cbSJens Wiklander high = (ctx->total[0] >> 29)
336817466cbSJens Wiklander | (ctx->total[1] << 3);
337817466cbSJens Wiklander low = (ctx->total[0] << 3);
338817466cbSJens Wiklander
339039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(low, msglen, 0);
340039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
341817466cbSJens Wiklander
342817466cbSJens Wiklander last = ctx->total[0] & 0x3F;
343817466cbSJens Wiklander padn = (last < 56) ? (56 - last) : (120 - last);
344817466cbSJens Wiklander
34532b31808SJens Wiklander ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
34632b31808SJens Wiklander if (ret != 0) {
347*b0563631STom Van Eyck goto exit;
34832b31808SJens Wiklander }
3493d3b0591SJens Wiklander
35032b31808SJens Wiklander ret = mbedtls_ripemd160_update(ctx, msglen, 8);
35132b31808SJens Wiklander if (ret != 0) {
352*b0563631STom Van Eyck goto exit;
35332b31808SJens Wiklander }
354817466cbSJens Wiklander
355039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0);
356039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4);
357039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8);
358039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
359039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
3603d3b0591SJens Wiklander
361*b0563631STom Van Eyck ret = 0;
362*b0563631STom Van Eyck
363*b0563631STom Van Eyck exit:
364*b0563631STom Van Eyck mbedtls_ripemd160_free(ctx);
365*b0563631STom Van Eyck return ret;
366817466cbSJens Wiklander }
367817466cbSJens Wiklander
3683d3b0591SJens Wiklander #endif /* ! MBEDTLS_RIPEMD160_ALT */
3693d3b0591SJens Wiklander
370817466cbSJens Wiklander /*
371817466cbSJens Wiklander * output = RIPEMD-160( input buffer )
372817466cbSJens Wiklander */
mbedtls_ripemd160(const unsigned char * input,size_t ilen,unsigned char output[20])37332b31808SJens Wiklander int mbedtls_ripemd160(const unsigned char *input,
3743d3b0591SJens Wiklander size_t ilen,
375817466cbSJens Wiklander unsigned char output[20])
376817466cbSJens Wiklander {
37711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
378817466cbSJens Wiklander mbedtls_ripemd160_context ctx;
379817466cbSJens Wiklander
380817466cbSJens Wiklander mbedtls_ripemd160_init(&ctx);
3813d3b0591SJens Wiklander
38232b31808SJens Wiklander if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) {
3833d3b0591SJens Wiklander goto exit;
38432b31808SJens Wiklander }
3853d3b0591SJens Wiklander
38632b31808SJens Wiklander if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) {
3873d3b0591SJens Wiklander goto exit;
38832b31808SJens Wiklander }
3893d3b0591SJens Wiklander
39032b31808SJens Wiklander if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
3913d3b0591SJens Wiklander goto exit;
39232b31808SJens Wiklander }
3933d3b0591SJens Wiklander
3943d3b0591SJens Wiklander exit:
395817466cbSJens Wiklander mbedtls_ripemd160_free(&ctx);
3963d3b0591SJens Wiklander
39732b31808SJens Wiklander return ret;
398817466cbSJens Wiklander }
399817466cbSJens Wiklander
400817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST)
401817466cbSJens Wiklander /*
402817466cbSJens Wiklander * Test vectors from the RIPEMD-160 paper and
403817466cbSJens Wiklander * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
404817466cbSJens Wiklander */
405817466cbSJens Wiklander #define TESTS 8
4063d3b0591SJens Wiklander static const unsigned char ripemd160_test_str[TESTS][81] =
407817466cbSJens Wiklander {
4083d3b0591SJens Wiklander { "" },
4093d3b0591SJens Wiklander { "a" },
4103d3b0591SJens Wiklander { "abc" },
4113d3b0591SJens Wiklander { "message digest" },
4123d3b0591SJens Wiklander { "abcdefghijklmnopqrstuvwxyz" },
4133d3b0591SJens Wiklander { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
4143d3b0591SJens Wiklander { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
41536905f94SGuido Vranken { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
4163d3b0591SJens Wiklander };
4173d3b0591SJens Wiklander
4183d3b0591SJens Wiklander static const size_t ripemd160_test_strlen[TESTS] =
4193d3b0591SJens Wiklander {
4203d3b0591SJens Wiklander 0, 1, 3, 14, 26, 56, 62, 80
421817466cbSJens Wiklander };
422817466cbSJens Wiklander
423817466cbSJens Wiklander static const unsigned char ripemd160_test_md[TESTS][20] =
424817466cbSJens Wiklander {
425817466cbSJens Wiklander { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
426817466cbSJens Wiklander 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
427817466cbSJens Wiklander { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
428817466cbSJens Wiklander 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
429817466cbSJens Wiklander { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
430817466cbSJens Wiklander 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
431817466cbSJens Wiklander { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
432817466cbSJens Wiklander 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
433817466cbSJens Wiklander { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
434817466cbSJens Wiklander 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
435817466cbSJens Wiklander { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
436817466cbSJens Wiklander 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
437817466cbSJens Wiklander { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
438817466cbSJens Wiklander 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
439817466cbSJens Wiklander { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
440817466cbSJens Wiklander 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
441817466cbSJens Wiklander };
442817466cbSJens Wiklander
443817466cbSJens Wiklander /*
444817466cbSJens Wiklander * Checkup routine
445817466cbSJens Wiklander */
mbedtls_ripemd160_self_test(int verbose)446817466cbSJens Wiklander int mbedtls_ripemd160_self_test(int verbose)
447817466cbSJens Wiklander {
4483d3b0591SJens Wiklander int i, ret = 0;
449817466cbSJens Wiklander unsigned char output[20];
450817466cbSJens Wiklander
45132b31808SJens Wiklander memset(output, 0, sizeof(output));
452817466cbSJens Wiklander
45332b31808SJens Wiklander for (i = 0; i < TESTS; i++) {
45432b31808SJens Wiklander if (verbose != 0) {
455817466cbSJens Wiklander mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1);
45632b31808SJens Wiklander }
457817466cbSJens Wiklander
45832b31808SJens Wiklander ret = mbedtls_ripemd160(ripemd160_test_str[i],
4593d3b0591SJens Wiklander ripemd160_test_strlen[i], output);
46032b31808SJens Wiklander if (ret != 0) {
4613d3b0591SJens Wiklander goto fail;
46232b31808SJens Wiklander }
463817466cbSJens Wiklander
46432b31808SJens Wiklander if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
4653d3b0591SJens Wiklander ret = 1;
4663d3b0591SJens Wiklander goto fail;
467817466cbSJens Wiklander }
468817466cbSJens Wiklander
46932b31808SJens Wiklander if (verbose != 0) {
470817466cbSJens Wiklander mbedtls_printf("passed\n");
471817466cbSJens Wiklander }
47232b31808SJens Wiklander }
473817466cbSJens Wiklander
47432b31808SJens Wiklander if (verbose != 0) {
475817466cbSJens Wiklander mbedtls_printf("\n");
47632b31808SJens Wiklander }
477817466cbSJens Wiklander
47832b31808SJens Wiklander return 0;
4793d3b0591SJens Wiklander
4803d3b0591SJens Wiklander fail:
48132b31808SJens Wiklander if (verbose != 0) {
4823d3b0591SJens Wiklander mbedtls_printf("failed\n");
48332b31808SJens Wiklander }
4843d3b0591SJens Wiklander
48532b31808SJens Wiklander return ret;
486817466cbSJens Wiklander }
487817466cbSJens Wiklander
488817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */
489817466cbSJens Wiklander
490817466cbSJens Wiklander #endif /* MBEDTLS_RIPEMD160_C */
491