xref: /optee_os/lib/libmbedtls/mbedtls/library/ripemd160.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
1817466cbSJens Wiklander /*
2817466cbSJens Wiklander  *  RIPE MD-160 implementation
3817466cbSJens Wiklander  *
47901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
57901324dSJerome Forissier  *  SPDX-License-Identifier: Apache-2.0
6817466cbSJens Wiklander  *
7817466cbSJens Wiklander  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8817466cbSJens Wiklander  *  not use this file except in compliance with the License.
9817466cbSJens Wiklander  *  You may obtain a copy of the License at
10817466cbSJens Wiklander  *
11817466cbSJens Wiklander  *  http://www.apache.org/licenses/LICENSE-2.0
12817466cbSJens Wiklander  *
13817466cbSJens Wiklander  *  Unless required by applicable law or agreed to in writing, software
14817466cbSJens Wiklander  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15817466cbSJens Wiklander  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16817466cbSJens Wiklander  *  See the License for the specific language governing permissions and
17817466cbSJens Wiklander  *  limitations under the License.
18817466cbSJens Wiklander  */
19817466cbSJens Wiklander 
20817466cbSJens Wiklander /*
21817466cbSJens Wiklander  *  The RIPEMD-160 algorithm was designed by RIPE in 1996
22817466cbSJens Wiklander  *  http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
23817466cbSJens Wiklander  *  http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
24817466cbSJens Wiklander  */
25817466cbSJens Wiklander 
267901324dSJerome Forissier #include "common.h"
27817466cbSJens Wiklander 
28817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C)
29817466cbSJens Wiklander 
30817466cbSJens Wiklander #include "mbedtls/ripemd160.h"
313d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
3211fa71b9SJerome Forissier #include "mbedtls/error.h"
33817466cbSJens Wiklander 
34817466cbSJens Wiklander #include <string.h>
35817466cbSJens Wiklander 
36817466cbSJens Wiklander #include "mbedtls/platform.h"
37817466cbSJens Wiklander 
383d3b0591SJens Wiklander #if !defined(MBEDTLS_RIPEMD160_ALT)
393d3b0591SJens Wiklander 
40817466cbSJens Wiklander void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx)
41817466cbSJens Wiklander {
42817466cbSJens Wiklander     memset(ctx, 0, sizeof(mbedtls_ripemd160_context));
43817466cbSJens Wiklander }
44817466cbSJens Wiklander 
45817466cbSJens Wiklander void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx)
46817466cbSJens Wiklander {
47*32b31808SJens Wiklander     if (ctx == NULL) {
48817466cbSJens Wiklander         return;
49*32b31808SJens Wiklander     }
50817466cbSJens Wiklander 
513d3b0591SJens Wiklander     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context));
52817466cbSJens Wiklander }
53817466cbSJens Wiklander 
54817466cbSJens Wiklander void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
55817466cbSJens Wiklander                              const mbedtls_ripemd160_context *src)
56817466cbSJens Wiklander {
57817466cbSJens Wiklander     *dst = *src;
58817466cbSJens Wiklander }
59817466cbSJens Wiklander 
60817466cbSJens Wiklander /*
61817466cbSJens Wiklander  * RIPEMD-160 context setup
62817466cbSJens Wiklander  */
63*32b31808SJens Wiklander int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx)
64817466cbSJens Wiklander {
65817466cbSJens Wiklander     ctx->total[0] = 0;
66817466cbSJens Wiklander     ctx->total[1] = 0;
67817466cbSJens Wiklander 
68817466cbSJens Wiklander     ctx->state[0] = 0x67452301;
69817466cbSJens Wiklander     ctx->state[1] = 0xEFCDAB89;
70817466cbSJens Wiklander     ctx->state[2] = 0x98BADCFE;
71817466cbSJens Wiklander     ctx->state[3] = 0x10325476;
72817466cbSJens Wiklander     ctx->state[4] = 0xC3D2E1F0;
733d3b0591SJens Wiklander 
74*32b31808SJens Wiklander     return 0;
75817466cbSJens Wiklander }
76817466cbSJens Wiklander 
77817466cbSJens Wiklander #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
78817466cbSJens Wiklander /*
79817466cbSJens Wiklander  * Process one block
80817466cbSJens Wiklander  */
813d3b0591SJens Wiklander int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx,
823d3b0591SJens Wiklander                                        const unsigned char data[64])
83817466cbSJens Wiklander {
84*32b31808SJens Wiklander     struct {
85817466cbSJens Wiklander         uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
867901324dSJerome Forissier     } local;
87817466cbSJens Wiklander 
88039e02dfSJerome Forissier     local.X[0] = MBEDTLS_GET_UINT32_LE(data,  0);
89039e02dfSJerome Forissier     local.X[1] = MBEDTLS_GET_UINT32_LE(data,  4);
90039e02dfSJerome Forissier     local.X[2] = MBEDTLS_GET_UINT32_LE(data,  8);
91039e02dfSJerome Forissier     local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12);
92039e02dfSJerome Forissier     local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16);
93039e02dfSJerome Forissier     local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20);
94039e02dfSJerome Forissier     local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24);
95039e02dfSJerome Forissier     local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28);
96039e02dfSJerome Forissier     local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32);
97039e02dfSJerome Forissier     local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36);
98039e02dfSJerome Forissier     local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40);
99039e02dfSJerome Forissier     local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44);
100039e02dfSJerome Forissier     local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48);
101039e02dfSJerome Forissier     local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52);
102039e02dfSJerome Forissier     local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56);
103039e02dfSJerome Forissier     local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60);
104817466cbSJens Wiklander 
1057901324dSJerome Forissier     local.A = local.Ap = ctx->state[0];
1067901324dSJerome Forissier     local.B = local.Bp = ctx->state[1];
1077901324dSJerome Forissier     local.C = local.Cp = ctx->state[2];
1087901324dSJerome Forissier     local.D = local.Dp = ctx->state[3];
1097901324dSJerome Forissier     local.E = local.Ep = ctx->state[4];
110817466cbSJens Wiklander 
1115b25c76aSJerome Forissier #define F1(x, y, z)   ((x) ^ (y) ^ (z))
1125b25c76aSJerome Forissier #define F2(x, y, z)   (((x) & (y)) | (~(x) & (z)))
1135b25c76aSJerome Forissier #define F3(x, y, z)   (((x) | ~(y)) ^ (z))
1145b25c76aSJerome Forissier #define F4(x, y, z)   (((x) & (z)) | ((y) & ~(z)))
1155b25c76aSJerome Forissier #define F5(x, y, z)   ((x) ^ ((y) | ~(z)))
116817466cbSJens Wiklander 
1175b25c76aSJerome Forissier #define S(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
118817466cbSJens Wiklander 
119817466cbSJens Wiklander #define P(a, b, c, d, e, r, s, f, k)                      \
1205b25c76aSJerome Forissier     do                                                      \
1215b25c76aSJerome Forissier     {                                                       \
1227901324dSJerome Forissier         (a) += f((b), (c), (d)) + local.X[r] + (k);       \
1235b25c76aSJerome Forissier         (a) = S((a), (s)) + (e);                          \
1245b25c76aSJerome Forissier         (c) = S((c), 10);                                 \
1255b25c76aSJerome Forissier     } while (0)
126817466cbSJens Wiklander 
127817466cbSJens Wiklander #define P2(a, b, c, d, e, r, s, rp, sp)                               \
1285b25c76aSJerome Forissier     do                                                                  \
1295b25c76aSJerome Forissier     {                                                                   \
1305b25c76aSJerome Forissier         P((a), (b), (c), (d), (e), (r), (s), F, K);                   \
1315b25c76aSJerome Forissier         P(a ## p, b ## p, c ## p, d ## p, e ## p,                      \
1325b25c76aSJerome Forissier           (rp), (sp), Fp, Kp);                                        \
1335b25c76aSJerome Forissier     } while (0)
134817466cbSJens Wiklander 
135817466cbSJens Wiklander #define F   F1
136817466cbSJens Wiklander #define K   0x00000000
137817466cbSJens Wiklander #define Fp  F5
138817466cbSJens Wiklander #define Kp  0x50A28BE6
1397901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  0, 11,  5,  8);
1407901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  1, 14, 14,  9);
1417901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  2, 15,  7,  9);
1427901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  3, 12,  0, 11);
1437901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A,  4,  5,  9, 13);
1447901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  5,  8,  2, 15);
1457901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  6,  7, 11, 15);
1467901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  7,  9,  4,  5);
1477901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  8, 11, 13,  7);
1487901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A,  9, 13,  6,  7);
1497901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15,  8);
1507901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D, 11, 15,  8, 11);
1517901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C, 12,  6,  1, 14);
1527901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B, 13,  7, 10, 14);
1537901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 14,  9,  3, 12);
1547901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E, 15,  8, 12,  6);
155817466cbSJens Wiklander #undef F
156817466cbSJens Wiklander #undef K
157817466cbSJens Wiklander #undef Fp
158817466cbSJens Wiklander #undef Kp
159817466cbSJens Wiklander 
160817466cbSJens Wiklander #define F   F2
161817466cbSJens Wiklander #define K   0x5A827999
162817466cbSJens Wiklander #define Fp  F4
163817466cbSJens Wiklander #define Kp  0x5C4DD124
1647901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  7,  7,  6,  9);
1657901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  4,  6, 11, 13);
1667901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B, 13,  8,  3, 15);
1677901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A,  1, 13,  7,  7);
1687901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E, 10, 11,  0, 12);
1697901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  6,  9, 13,  8);
1707901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C, 15,  7,  5,  9);
1717901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  3, 15, 10, 11);
1727901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 12,  7, 14,  7);
1737901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  0, 12, 15,  7);
1747901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  9, 15,  8, 12);
1757901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  5,  9, 12,  7);
1767901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  2, 11,  4,  6);
1777901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 14,  7,  9, 15);
1787901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E, 11, 13,  1, 13);
1797901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  8, 12,  2, 11);
180817466cbSJens Wiklander #undef F
181817466cbSJens Wiklander #undef K
182817466cbSJens Wiklander #undef Fp
183817466cbSJens Wiklander #undef Kp
184817466cbSJens Wiklander 
185817466cbSJens Wiklander #define F   F3
186817466cbSJens Wiklander #define K   0x6ED9EBA1
187817466cbSJens Wiklander #define Fp  F3
188817466cbSJens Wiklander #define Kp  0x6D703EF3
1897901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  3, 11, 15,  9);
1907901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B, 10, 13,  5,  7);
1917901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 14,  6,  1, 15);
1927901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  4,  7,  3, 11);
1937901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  9, 14,  7,  8);
1947901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C, 15,  9, 14,  6);
1957901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  8, 13,  6,  6);
1967901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A,  1, 15,  9, 14);
1977901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  2, 14, 11, 12);
1987901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  7,  8,  8, 13);
1997901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  0, 13, 12,  5);
2007901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  6,  6,  2, 14);
2017901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 13,  5, 10, 13);
2027901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E, 11, 12,  0, 13);
2037901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  5,  7,  4,  7);
2047901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C, 12,  5, 13,  5);
205817466cbSJens Wiklander #undef F
206817466cbSJens Wiklander #undef K
207817466cbSJens Wiklander #undef Fp
208817466cbSJens Wiklander #undef Kp
209817466cbSJens Wiklander 
210817466cbSJens Wiklander #define F   F4
211817466cbSJens Wiklander #define K   0x8F1BBCDC
212817466cbSJens Wiklander #define Fp  F2
213817466cbSJens Wiklander #define Kp  0x7A6D76E9
2147901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  1, 11,  8, 15);
2157901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A,  9, 12,  6,  5);
2167901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E, 11, 14,  4,  8);
2177901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D, 10, 15,  1, 11);
2187901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  0, 14,  3, 14);
2197901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  8, 15, 11, 14);
2207901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 12,  9, 15,  6);
2217901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  4,  8,  0, 14);
2227901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D, 13,  9,  5,  6);
2237901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  3, 14, 12,  9);
2247901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  7,  5,  2, 12);
2257901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 15,  6, 13,  9);
2267901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E, 14,  8,  9, 12);
2277901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  5,  6,  7,  5);
2287901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  6,  5, 10, 15);
2297901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  2, 12, 14,  8);
230817466cbSJens Wiklander #undef F
231817466cbSJens Wiklander #undef K
232817466cbSJens Wiklander #undef Fp
233817466cbSJens Wiklander #undef Kp
234817466cbSJens Wiklander 
235817466cbSJens Wiklander #define F   F5
236817466cbSJens Wiklander #define K   0xA953FD4E
237817466cbSJens Wiklander #define Fp  F1
238817466cbSJens Wiklander #define Kp  0x00000000
2397901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A,  4,  9, 12,  8);
2407901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  0, 15, 15,  5);
2417901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D,  5,  5, 10, 12);
2427901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  9, 11,  4,  9);
2437901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  7,  6,  1, 12);
2447901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 12,  8,  5,  5);
2457901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  2, 13,  8, 14);
2467901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D, 10, 12,  7,  6);
2477901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C, 14,  5,  6,  8);
2487901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B,  1, 12,  2, 13);
2497901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A,  3, 13, 13,  6);
2507901324dSJerome Forissier     P2(local.A, local.B, local.C, local.D, local.E,  8, 14, 14,  5);
2517901324dSJerome Forissier     P2(local.E, local.A, local.B, local.C, local.D, 11, 11,  0, 15);
2527901324dSJerome Forissier     P2(local.D, local.E, local.A, local.B, local.C,  6,  8,  3, 13);
2537901324dSJerome Forissier     P2(local.C, local.D, local.E, local.A, local.B, 15,  5,  9, 11);
2547901324dSJerome Forissier     P2(local.B, local.C, local.D, local.E, local.A, 13,  6, 11, 11);
255817466cbSJens Wiklander #undef F
256817466cbSJens Wiklander #undef K
257817466cbSJens Wiklander #undef Fp
258817466cbSJens Wiklander #undef Kp
259817466cbSJens Wiklander 
2607901324dSJerome Forissier     local.C       = ctx->state[1] + local.C + local.Dp;
2617901324dSJerome Forissier     ctx->state[1] = ctx->state[2] + local.D + local.Ep;
2627901324dSJerome Forissier     ctx->state[2] = ctx->state[3] + local.E + local.Ap;
2637901324dSJerome Forissier     ctx->state[3] = ctx->state[4] + local.A + local.Bp;
2647901324dSJerome Forissier     ctx->state[4] = ctx->state[0] + local.B + local.Cp;
2657901324dSJerome Forissier     ctx->state[0] = local.C;
2667901324dSJerome Forissier 
2677901324dSJerome Forissier     /* Zeroise variables to clear sensitive data from memory. */
2687901324dSJerome Forissier     mbedtls_platform_zeroize(&local, sizeof(local));
2693d3b0591SJens Wiklander 
270*32b31808SJens Wiklander     return 0;
271817466cbSJens Wiklander }
2723d3b0591SJens Wiklander 
273817466cbSJens Wiklander #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
274817466cbSJens Wiklander 
275817466cbSJens Wiklander /*
276817466cbSJens Wiklander  * RIPEMD-160 process buffer
277817466cbSJens Wiklander  */
278*32b31808SJens Wiklander int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
2793d3b0591SJens Wiklander                              const unsigned char *input,
2803d3b0591SJens Wiklander                              size_t ilen)
281817466cbSJens Wiklander {
28211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
283817466cbSJens Wiklander     size_t fill;
284817466cbSJens Wiklander     uint32_t left;
285817466cbSJens Wiklander 
286*32b31808SJens Wiklander     if (ilen == 0) {
287*32b31808SJens Wiklander         return 0;
288*32b31808SJens Wiklander     }
289817466cbSJens Wiklander 
290817466cbSJens Wiklander     left = ctx->total[0] & 0x3F;
291817466cbSJens Wiklander     fill = 64 - left;
292817466cbSJens Wiklander 
293817466cbSJens Wiklander     ctx->total[0] += (uint32_t) ilen;
294817466cbSJens Wiklander     ctx->total[0] &= 0xFFFFFFFF;
295817466cbSJens Wiklander 
296*32b31808SJens Wiklander     if (ctx->total[0] < (uint32_t) ilen) {
297817466cbSJens Wiklander         ctx->total[1]++;
298*32b31808SJens Wiklander     }
299817466cbSJens Wiklander 
300*32b31808SJens Wiklander     if (left && ilen >= fill) {
301817466cbSJens Wiklander         memcpy((void *) (ctx->buffer + left), input, fill);
3023d3b0591SJens Wiklander 
303*32b31808SJens Wiklander         if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) {
304*32b31808SJens Wiklander             return ret;
305*32b31808SJens Wiklander         }
3063d3b0591SJens Wiklander 
307817466cbSJens Wiklander         input += fill;
308817466cbSJens Wiklander         ilen  -= fill;
309817466cbSJens Wiklander         left = 0;
310817466cbSJens Wiklander     }
311817466cbSJens Wiklander 
312*32b31808SJens Wiklander     while (ilen >= 64) {
313*32b31808SJens Wiklander         if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) {
314*32b31808SJens Wiklander             return ret;
315*32b31808SJens Wiklander         }
3163d3b0591SJens Wiklander 
317817466cbSJens Wiklander         input += 64;
318817466cbSJens Wiklander         ilen  -= 64;
319817466cbSJens Wiklander     }
320817466cbSJens Wiklander 
321*32b31808SJens Wiklander     if (ilen > 0) {
322817466cbSJens Wiklander         memcpy((void *) (ctx->buffer + left), input, ilen);
323817466cbSJens Wiklander     }
3243d3b0591SJens Wiklander 
325*32b31808SJens Wiklander     return 0;
326817466cbSJens Wiklander }
327817466cbSJens Wiklander 
328817466cbSJens Wiklander static const unsigned char ripemd160_padding[64] =
329817466cbSJens Wiklander {
330817466cbSJens Wiklander     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331817466cbSJens Wiklander     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332817466cbSJens Wiklander     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
333817466cbSJens Wiklander     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
334817466cbSJens Wiklander };
335817466cbSJens Wiklander 
336817466cbSJens Wiklander /*
337817466cbSJens Wiklander  * RIPEMD-160 final digest
338817466cbSJens Wiklander  */
339*32b31808SJens Wiklander int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
3403d3b0591SJens Wiklander                              unsigned char output[20])
341817466cbSJens Wiklander {
34211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
343817466cbSJens Wiklander     uint32_t last, padn;
344817466cbSJens Wiklander     uint32_t high, low;
345817466cbSJens Wiklander     unsigned char msglen[8];
346817466cbSJens Wiklander 
347817466cbSJens Wiklander     high = (ctx->total[0] >> 29)
348817466cbSJens Wiklander            | (ctx->total[1] <<  3);
349817466cbSJens Wiklander     low  = (ctx->total[0] <<  3);
350817466cbSJens Wiklander 
351039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(low,  msglen, 0);
352039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(high, msglen, 4);
353817466cbSJens Wiklander 
354817466cbSJens Wiklander     last = ctx->total[0] & 0x3F;
355817466cbSJens Wiklander     padn = (last < 56) ? (56 - last) : (120 - last);
356817466cbSJens Wiklander 
357*32b31808SJens Wiklander     ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn);
358*32b31808SJens Wiklander     if (ret != 0) {
359*32b31808SJens Wiklander         return ret;
360*32b31808SJens Wiklander     }
3613d3b0591SJens Wiklander 
362*32b31808SJens Wiklander     ret = mbedtls_ripemd160_update(ctx, msglen, 8);
363*32b31808SJens Wiklander     if (ret != 0) {
364*32b31808SJens Wiklander         return ret;
365*32b31808SJens Wiklander     }
366817466cbSJens Wiklander 
367039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(ctx->state[0], output,  0);
368039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(ctx->state[1], output,  4);
369039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(ctx->state[2], output,  8);
370039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12);
371039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16);
3723d3b0591SJens Wiklander 
373*32b31808SJens Wiklander     return 0;
374817466cbSJens Wiklander }
375817466cbSJens Wiklander 
3763d3b0591SJens Wiklander #endif /* ! MBEDTLS_RIPEMD160_ALT */
3773d3b0591SJens Wiklander 
378817466cbSJens Wiklander /*
379817466cbSJens Wiklander  * output = RIPEMD-160( input buffer )
380817466cbSJens Wiklander  */
381*32b31808SJens Wiklander int mbedtls_ripemd160(const unsigned char *input,
3823d3b0591SJens Wiklander                       size_t ilen,
383817466cbSJens Wiklander                       unsigned char output[20])
384817466cbSJens Wiklander {
38511fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
386817466cbSJens Wiklander     mbedtls_ripemd160_context ctx;
387817466cbSJens Wiklander 
388817466cbSJens Wiklander     mbedtls_ripemd160_init(&ctx);
3893d3b0591SJens Wiklander 
390*32b31808SJens Wiklander     if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) {
3913d3b0591SJens Wiklander         goto exit;
392*32b31808SJens Wiklander     }
3933d3b0591SJens Wiklander 
394*32b31808SJens Wiklander     if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) {
3953d3b0591SJens Wiklander         goto exit;
396*32b31808SJens Wiklander     }
3973d3b0591SJens Wiklander 
398*32b31808SJens Wiklander     if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) {
3993d3b0591SJens Wiklander         goto exit;
400*32b31808SJens Wiklander     }
4013d3b0591SJens Wiklander 
4023d3b0591SJens Wiklander exit:
403817466cbSJens Wiklander     mbedtls_ripemd160_free(&ctx);
4043d3b0591SJens Wiklander 
405*32b31808SJens Wiklander     return ret;
406817466cbSJens Wiklander }
407817466cbSJens Wiklander 
408817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST)
409817466cbSJens Wiklander /*
410817466cbSJens Wiklander  * Test vectors from the RIPEMD-160 paper and
411817466cbSJens Wiklander  * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
412817466cbSJens Wiklander  */
413817466cbSJens Wiklander #define TESTS   8
4143d3b0591SJens Wiklander static const unsigned char ripemd160_test_str[TESTS][81] =
415817466cbSJens Wiklander {
4163d3b0591SJens Wiklander     { "" },
4173d3b0591SJens Wiklander     { "a" },
4183d3b0591SJens Wiklander     { "abc" },
4193d3b0591SJens Wiklander     { "message digest" },
4203d3b0591SJens Wiklander     { "abcdefghijklmnopqrstuvwxyz" },
4213d3b0591SJens Wiklander     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
4223d3b0591SJens Wiklander     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
42336905f94SGuido Vranken     { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
4243d3b0591SJens Wiklander };
4253d3b0591SJens Wiklander 
4263d3b0591SJens Wiklander static const size_t ripemd160_test_strlen[TESTS] =
4273d3b0591SJens Wiklander {
4283d3b0591SJens Wiklander     0, 1, 3, 14, 26, 56, 62, 80
429817466cbSJens Wiklander };
430817466cbSJens Wiklander 
431817466cbSJens Wiklander static const unsigned char ripemd160_test_md[TESTS][20] =
432817466cbSJens Wiklander {
433817466cbSJens Wiklander     { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
434817466cbSJens Wiklander       0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
435817466cbSJens Wiklander     { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
436817466cbSJens Wiklander       0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
437817466cbSJens Wiklander     { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
438817466cbSJens Wiklander       0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
439817466cbSJens Wiklander     { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
440817466cbSJens Wiklander       0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
441817466cbSJens Wiklander     { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
442817466cbSJens Wiklander       0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
443817466cbSJens Wiklander     { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
444817466cbSJens Wiklander       0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
445817466cbSJens Wiklander     { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
446817466cbSJens Wiklander       0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
447817466cbSJens Wiklander     { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
448817466cbSJens Wiklander       0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
449817466cbSJens Wiklander };
450817466cbSJens Wiklander 
451817466cbSJens Wiklander /*
452817466cbSJens Wiklander  * Checkup routine
453817466cbSJens Wiklander  */
454817466cbSJens Wiklander int mbedtls_ripemd160_self_test(int verbose)
455817466cbSJens Wiklander {
4563d3b0591SJens Wiklander     int i, ret = 0;
457817466cbSJens Wiklander     unsigned char output[20];
458817466cbSJens Wiklander 
459*32b31808SJens Wiklander     memset(output, 0, sizeof(output));
460817466cbSJens Wiklander 
461*32b31808SJens Wiklander     for (i = 0; i < TESTS; i++) {
462*32b31808SJens Wiklander         if (verbose != 0) {
463817466cbSJens Wiklander             mbedtls_printf("  RIPEMD-160 test #%d: ", i + 1);
464*32b31808SJens Wiklander         }
465817466cbSJens Wiklander 
466*32b31808SJens Wiklander         ret = mbedtls_ripemd160(ripemd160_test_str[i],
4673d3b0591SJens Wiklander                                 ripemd160_test_strlen[i], output);
468*32b31808SJens Wiklander         if (ret != 0) {
4693d3b0591SJens Wiklander             goto fail;
470*32b31808SJens Wiklander         }
471817466cbSJens Wiklander 
472*32b31808SJens Wiklander         if (memcmp(output, ripemd160_test_md[i], 20) != 0) {
4733d3b0591SJens Wiklander             ret = 1;
4743d3b0591SJens Wiklander             goto fail;
475817466cbSJens Wiklander         }
476817466cbSJens Wiklander 
477*32b31808SJens Wiklander         if (verbose != 0) {
478817466cbSJens Wiklander             mbedtls_printf("passed\n");
479817466cbSJens Wiklander         }
480*32b31808SJens Wiklander     }
481817466cbSJens Wiklander 
482*32b31808SJens Wiklander     if (verbose != 0) {
483817466cbSJens Wiklander         mbedtls_printf("\n");
484*32b31808SJens Wiklander     }
485817466cbSJens Wiklander 
486*32b31808SJens Wiklander     return 0;
4873d3b0591SJens Wiklander 
4883d3b0591SJens Wiklander fail:
489*32b31808SJens Wiklander     if (verbose != 0) {
4903d3b0591SJens Wiklander         mbedtls_printf("failed\n");
491*32b31808SJens Wiklander     }
4923d3b0591SJens Wiklander 
493*32b31808SJens Wiklander     return ret;
494817466cbSJens Wiklander }
495817466cbSJens Wiklander 
496817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */
497817466cbSJens Wiklander 
498817466cbSJens Wiklander #endif /* MBEDTLS_RIPEMD160_C */
499