xref: /optee_os/lib/libmbedtls/mbedtls/library/ripemd160.c (revision b0563631928755fe864b97785160fb3088e9efdc)
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