xref: /optee_os/lib/libmbedtls/mbedtls/library/ripemd160.c (revision 039e02df2716a0ed886b56e1e07b7ac1d8597228)
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 #if defined(MBEDTLS_SELF_TEST)
37817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C)
38817466cbSJens Wiklander #include "mbedtls/platform.h"
39817466cbSJens Wiklander #else
40817466cbSJens Wiklander #include <stdio.h>
41817466cbSJens Wiklander #define mbedtls_printf printf
42817466cbSJens Wiklander #endif /* MBEDTLS_PLATFORM_C */
43817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */
44817466cbSJens Wiklander 
453d3b0591SJens Wiklander #if !defined(MBEDTLS_RIPEMD160_ALT)
463d3b0591SJens Wiklander 
47817466cbSJens Wiklander void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
48817466cbSJens Wiklander {
49817466cbSJens Wiklander     memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
50817466cbSJens Wiklander }
51817466cbSJens Wiklander 
52817466cbSJens Wiklander void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
53817466cbSJens Wiklander {
54817466cbSJens Wiklander     if( ctx == NULL )
55817466cbSJens Wiklander         return;
56817466cbSJens Wiklander 
573d3b0591SJens Wiklander     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
58817466cbSJens Wiklander }
59817466cbSJens Wiklander 
60817466cbSJens Wiklander void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
61817466cbSJens Wiklander                         const mbedtls_ripemd160_context *src )
62817466cbSJens Wiklander {
63817466cbSJens Wiklander     *dst = *src;
64817466cbSJens Wiklander }
65817466cbSJens Wiklander 
66817466cbSJens Wiklander /*
67817466cbSJens Wiklander  * RIPEMD-160 context setup
68817466cbSJens Wiklander  */
693d3b0591SJens Wiklander int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
70817466cbSJens Wiklander {
71817466cbSJens Wiklander     ctx->total[0] = 0;
72817466cbSJens Wiklander     ctx->total[1] = 0;
73817466cbSJens Wiklander 
74817466cbSJens Wiklander     ctx->state[0] = 0x67452301;
75817466cbSJens Wiklander     ctx->state[1] = 0xEFCDAB89;
76817466cbSJens Wiklander     ctx->state[2] = 0x98BADCFE;
77817466cbSJens Wiklander     ctx->state[3] = 0x10325476;
78817466cbSJens Wiklander     ctx->state[4] = 0xC3D2E1F0;
793d3b0591SJens Wiklander 
803d3b0591SJens Wiklander     return( 0 );
81817466cbSJens Wiklander }
82817466cbSJens Wiklander 
833d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED)
843d3b0591SJens Wiklander void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
853d3b0591SJens Wiklander {
863d3b0591SJens Wiklander     mbedtls_ripemd160_starts_ret( ctx );
873d3b0591SJens Wiklander }
883d3b0591SJens Wiklander #endif
893d3b0591SJens Wiklander 
90817466cbSJens Wiklander #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
91817466cbSJens Wiklander /*
92817466cbSJens Wiklander  * Process one block
93817466cbSJens Wiklander  */
943d3b0591SJens Wiklander int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
953d3b0591SJens Wiklander                                         const unsigned char data[64] )
96817466cbSJens Wiklander {
977901324dSJerome Forissier     struct
987901324dSJerome Forissier     {
99817466cbSJens Wiklander         uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
1007901324dSJerome Forissier     } local;
101817466cbSJens Wiklander 
102*039e02dfSJerome Forissier     local.X[ 0] = MBEDTLS_GET_UINT32_LE( data,  0 );
103*039e02dfSJerome Forissier     local.X[ 1] = MBEDTLS_GET_UINT32_LE( data,  4 );
104*039e02dfSJerome Forissier     local.X[ 2] = MBEDTLS_GET_UINT32_LE( data,  8 );
105*039e02dfSJerome Forissier     local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
106*039e02dfSJerome Forissier     local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
107*039e02dfSJerome Forissier     local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
108*039e02dfSJerome Forissier     local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
109*039e02dfSJerome Forissier     local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
110*039e02dfSJerome Forissier     local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
111*039e02dfSJerome Forissier     local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
112*039e02dfSJerome Forissier     local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
113*039e02dfSJerome Forissier     local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
114*039e02dfSJerome Forissier     local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
115*039e02dfSJerome Forissier     local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
116*039e02dfSJerome Forissier     local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
117*039e02dfSJerome Forissier     local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
118817466cbSJens Wiklander 
1197901324dSJerome Forissier     local.A = local.Ap = ctx->state[0];
1207901324dSJerome Forissier     local.B = local.Bp = ctx->state[1];
1217901324dSJerome Forissier     local.C = local.Cp = ctx->state[2];
1227901324dSJerome Forissier     local.D = local.Dp = ctx->state[3];
1237901324dSJerome Forissier     local.E = local.Ep = ctx->state[4];
124817466cbSJens Wiklander 
1255b25c76aSJerome Forissier #define F1( x, y, z )   ( (x) ^ (y) ^ (z) )
1265b25c76aSJerome Forissier #define F2( x, y, z )   ( ( (x) & (y) ) | ( ~(x) & (z) ) )
1275b25c76aSJerome Forissier #define F3( x, y, z )   ( ( (x) | ~(y) ) ^ (z) )
1285b25c76aSJerome Forissier #define F4( x, y, z )   ( ( (x) & (z) ) | ( (y) & ~(z) ) )
1295b25c76aSJerome Forissier #define F5( x, y, z )   ( (x) ^ ( (y) | ~(z) ) )
130817466cbSJens Wiklander 
1315b25c76aSJerome Forissier #define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
132817466cbSJens Wiklander 
133817466cbSJens Wiklander #define P( a, b, c, d, e, r, s, f, k )                      \
1345b25c76aSJerome Forissier     do                                                      \
1355b25c76aSJerome Forissier     {                                                       \
1367901324dSJerome Forissier         (a) += f( (b), (c), (d) ) + local.X[r] + (k);       \
1375b25c76aSJerome Forissier         (a) = S( (a), (s) ) + (e);                          \
1385b25c76aSJerome Forissier         (c) = S( (c), 10 );                                 \
1395b25c76aSJerome Forissier     } while( 0 )
140817466cbSJens Wiklander 
141817466cbSJens Wiklander #define P2( a, b, c, d, e, r, s, rp, sp )                               \
1425b25c76aSJerome Forissier     do                                                                  \
1435b25c76aSJerome Forissier     {                                                                   \
1445b25c76aSJerome Forissier         P( (a), (b), (c), (d), (e), (r), (s), F, K );                   \
1455b25c76aSJerome Forissier         P( a ## p, b ## p, c ## p, d ## p, e ## p,                      \
1465b25c76aSJerome Forissier            (rp), (sp), Fp, Kp );                                        \
1475b25c76aSJerome Forissier     } while( 0 )
148817466cbSJens Wiklander 
149817466cbSJens Wiklander #define F   F1
150817466cbSJens Wiklander #define K   0x00000000
151817466cbSJens Wiklander #define Fp  F5
152817466cbSJens Wiklander #define Kp  0x50A28BE6
1537901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  0, 11,  5,  8 );
1547901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  1, 14, 14,  9 );
1557901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  2, 15,  7,  9 );
1567901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  3, 12,  0, 11 );
1577901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A,  4,  5,  9, 13 );
1587901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  5,  8,  2, 15 );
1597901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  6,  7, 11, 15 );
1607901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  7,  9,  4,  5 );
1617901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  8, 11, 13,  7 );
1627901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A,  9, 13,  6,  7 );
1637901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15,  8 );
1647901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D, 11, 15,  8, 11 );
1657901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C, 12,  6,  1, 14 );
1667901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B, 13,  7, 10, 14 );
1677901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 14,  9,  3, 12 );
1687901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E, 15,  8, 12,  6 );
169817466cbSJens Wiklander #undef F
170817466cbSJens Wiklander #undef K
171817466cbSJens Wiklander #undef Fp
172817466cbSJens Wiklander #undef Kp
173817466cbSJens Wiklander 
174817466cbSJens Wiklander #define F   F2
175817466cbSJens Wiklander #define K   0x5A827999
176817466cbSJens Wiklander #define Fp  F4
177817466cbSJens Wiklander #define Kp  0x5C4DD124
1787901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  7,  7,  6,  9 );
1797901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  4,  6, 11, 13 );
1807901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B, 13,  8,  3, 15 );
1817901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A,  1, 13,  7,  7 );
1827901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E, 10, 11,  0, 12 );
1837901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  6,  9, 13,  8 );
1847901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C, 15,  7,  5,  9 );
1857901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  3, 15, 10, 11 );
1867901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 12,  7, 14,  7 );
1877901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  0, 12, 15,  7 );
1887901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  9, 15,  8, 12 );
1897901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  5,  9, 12,  7 );
1907901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  2, 11,  4,  6 );
1917901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 14,  7,  9, 15 );
1927901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E, 11, 13,  1, 13 );
1937901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  8, 12,  2, 11 );
194817466cbSJens Wiklander #undef F
195817466cbSJens Wiklander #undef K
196817466cbSJens Wiklander #undef Fp
197817466cbSJens Wiklander #undef Kp
198817466cbSJens Wiklander 
199817466cbSJens Wiklander #define F   F3
200817466cbSJens Wiklander #define K   0x6ED9EBA1
201817466cbSJens Wiklander #define Fp  F3
202817466cbSJens Wiklander #define Kp  0x6D703EF3
2037901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  3, 11, 15,  9 );
2047901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B, 10, 13,  5,  7 );
2057901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 14,  6,  1, 15 );
2067901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  4,  7,  3, 11 );
2077901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  9, 14,  7,  8 );
2087901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C, 15,  9, 14,  6 );
2097901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  8, 13,  6,  6 );
2107901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A,  1, 15,  9, 14 );
2117901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  2, 14, 11, 12 );
2127901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  7,  8,  8, 13 );
2137901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  0, 13, 12,  5 );
2147901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  6,  6,  2, 14 );
2157901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 13,  5, 10, 13 );
2167901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E, 11, 12,  0, 13 );
2177901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  5,  7,  4,  7 );
2187901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C, 12,  5, 13,  5 );
219817466cbSJens Wiklander #undef F
220817466cbSJens Wiklander #undef K
221817466cbSJens Wiklander #undef Fp
222817466cbSJens Wiklander #undef Kp
223817466cbSJens Wiklander 
224817466cbSJens Wiklander #define F   F4
225817466cbSJens Wiklander #define K   0x8F1BBCDC
226817466cbSJens Wiklander #define Fp  F2
227817466cbSJens Wiklander #define Kp  0x7A6D76E9
2287901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  1, 11,  8, 15 );
2297901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A,  9, 12,  6,  5 );
2307901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E, 11, 14,  4,  8 );
2317901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D, 10, 15,  1, 11 );
2327901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  0, 14,  3, 14 );
2337901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  8, 15, 11, 14 );
2347901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 12,  9, 15,  6 );
2357901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  4,  8,  0, 14 );
2367901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D, 13,  9,  5,  6 );
2377901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  3, 14, 12,  9 );
2387901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  7,  5,  2, 12 );
2397901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 15,  6, 13,  9 );
2407901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E, 14,  8,  9, 12 );
2417901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  5,  6,  7,  5 );
2427901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  6,  5, 10, 15 );
2437901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  2, 12, 14,  8 );
244817466cbSJens Wiklander #undef F
245817466cbSJens Wiklander #undef K
246817466cbSJens Wiklander #undef Fp
247817466cbSJens Wiklander #undef Kp
248817466cbSJens Wiklander 
249817466cbSJens Wiklander #define F   F5
250817466cbSJens Wiklander #define K   0xA953FD4E
251817466cbSJens Wiklander #define Fp  F1
252817466cbSJens Wiklander #define Kp  0x00000000
2537901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A,  4,  9, 12,  8 );
2547901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  0, 15, 15,  5 );
2557901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D,  5,  5, 10, 12 );
2567901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  9, 11,  4,  9 );
2577901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  7,  6,  1, 12 );
2587901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 12,  8,  5,  5 );
2597901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  2, 13,  8, 14 );
2607901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D, 10, 12,  7,  6 );
2617901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C, 14,  5,  6,  8 );
2627901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B,  1, 12,  2, 13 );
2637901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A,  3, 13, 13,  6 );
2647901324dSJerome Forissier     P2( local.A, local.B, local.C, local.D, local.E,  8, 14, 14,  5 );
2657901324dSJerome Forissier     P2( local.E, local.A, local.B, local.C, local.D, 11, 11,  0, 15 );
2667901324dSJerome Forissier     P2( local.D, local.E, local.A, local.B, local.C,  6,  8,  3, 13 );
2677901324dSJerome Forissier     P2( local.C, local.D, local.E, local.A, local.B, 15,  5,  9, 11 );
2687901324dSJerome Forissier     P2( local.B, local.C, local.D, local.E, local.A, 13,  6, 11, 11 );
269817466cbSJens Wiklander #undef F
270817466cbSJens Wiklander #undef K
271817466cbSJens Wiklander #undef Fp
272817466cbSJens Wiklander #undef Kp
273817466cbSJens Wiklander 
2747901324dSJerome Forissier     local.C       = ctx->state[1] + local.C + local.Dp;
2757901324dSJerome Forissier     ctx->state[1] = ctx->state[2] + local.D + local.Ep;
2767901324dSJerome Forissier     ctx->state[2] = ctx->state[3] + local.E + local.Ap;
2777901324dSJerome Forissier     ctx->state[3] = ctx->state[4] + local.A + local.Bp;
2787901324dSJerome Forissier     ctx->state[4] = ctx->state[0] + local.B + local.Cp;
2797901324dSJerome Forissier     ctx->state[0] = local.C;
2807901324dSJerome Forissier 
2817901324dSJerome Forissier     /* Zeroise variables to clear sensitive data from memory. */
2827901324dSJerome Forissier     mbedtls_platform_zeroize( &local, sizeof( local ) );
2833d3b0591SJens Wiklander 
2843d3b0591SJens Wiklander     return( 0 );
285817466cbSJens Wiklander }
2863d3b0591SJens Wiklander 
2873d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED)
2883d3b0591SJens Wiklander void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
2893d3b0591SJens Wiklander                                 const unsigned char data[64] )
2903d3b0591SJens Wiklander {
2913d3b0591SJens Wiklander     mbedtls_internal_ripemd160_process( ctx, data );
2923d3b0591SJens Wiklander }
2933d3b0591SJens Wiklander #endif
294817466cbSJens Wiklander #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
295817466cbSJens Wiklander 
296817466cbSJens Wiklander /*
297817466cbSJens Wiklander  * RIPEMD-160 process buffer
298817466cbSJens Wiklander  */
2993d3b0591SJens Wiklander int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
3003d3b0591SJens Wiklander                                   const unsigned char *input,
3013d3b0591SJens Wiklander                                   size_t ilen )
302817466cbSJens Wiklander {
30311fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
304817466cbSJens Wiklander     size_t fill;
305817466cbSJens Wiklander     uint32_t left;
306817466cbSJens Wiklander 
307817466cbSJens Wiklander     if( ilen == 0 )
3083d3b0591SJens Wiklander         return( 0 );
309817466cbSJens Wiklander 
310817466cbSJens Wiklander     left = ctx->total[0] & 0x3F;
311817466cbSJens Wiklander     fill = 64 - left;
312817466cbSJens Wiklander 
313817466cbSJens Wiklander     ctx->total[0] += (uint32_t) ilen;
314817466cbSJens Wiklander     ctx->total[0] &= 0xFFFFFFFF;
315817466cbSJens Wiklander 
316817466cbSJens Wiklander     if( ctx->total[0] < (uint32_t) ilen )
317817466cbSJens Wiklander         ctx->total[1]++;
318817466cbSJens Wiklander 
319817466cbSJens Wiklander     if( left && ilen >= fill )
320817466cbSJens Wiklander     {
321817466cbSJens Wiklander         memcpy( (void *) (ctx->buffer + left), input, fill );
3223d3b0591SJens Wiklander 
3233d3b0591SJens Wiklander         if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
3243d3b0591SJens Wiklander             return( ret );
3253d3b0591SJens Wiklander 
326817466cbSJens Wiklander         input += fill;
327817466cbSJens Wiklander         ilen  -= fill;
328817466cbSJens Wiklander         left = 0;
329817466cbSJens Wiklander     }
330817466cbSJens Wiklander 
331817466cbSJens Wiklander     while( ilen >= 64 )
332817466cbSJens Wiklander     {
3333d3b0591SJens Wiklander         if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
3343d3b0591SJens Wiklander             return( ret );
3353d3b0591SJens Wiklander 
336817466cbSJens Wiklander         input += 64;
337817466cbSJens Wiklander         ilen  -= 64;
338817466cbSJens Wiklander     }
339817466cbSJens Wiklander 
340817466cbSJens Wiklander     if( ilen > 0 )
341817466cbSJens Wiklander     {
342817466cbSJens Wiklander         memcpy( (void *) (ctx->buffer + left), input, ilen );
343817466cbSJens Wiklander     }
3443d3b0591SJens Wiklander 
3453d3b0591SJens Wiklander     return( 0 );
346817466cbSJens Wiklander }
347817466cbSJens Wiklander 
3483d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED)
3493d3b0591SJens Wiklander void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
3503d3b0591SJens Wiklander                                const unsigned char *input,
3513d3b0591SJens Wiklander                                size_t ilen )
3523d3b0591SJens Wiklander {
3533d3b0591SJens Wiklander     mbedtls_ripemd160_update_ret( ctx, input, ilen );
3543d3b0591SJens Wiklander }
3553d3b0591SJens Wiklander #endif
3563d3b0591SJens Wiklander 
357817466cbSJens Wiklander static const unsigned char ripemd160_padding[64] =
358817466cbSJens Wiklander {
359817466cbSJens Wiklander  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
360817466cbSJens Wiklander     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
361817466cbSJens Wiklander     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
362817466cbSJens Wiklander     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
363817466cbSJens Wiklander };
364817466cbSJens Wiklander 
365817466cbSJens Wiklander /*
366817466cbSJens Wiklander  * RIPEMD-160 final digest
367817466cbSJens Wiklander  */
3683d3b0591SJens Wiklander int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
3693d3b0591SJens Wiklander                                   unsigned char output[20] )
370817466cbSJens Wiklander {
37111fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
372817466cbSJens Wiklander     uint32_t last, padn;
373817466cbSJens Wiklander     uint32_t high, low;
374817466cbSJens Wiklander     unsigned char msglen[8];
375817466cbSJens Wiklander 
376817466cbSJens Wiklander     high = ( ctx->total[0] >> 29 )
377817466cbSJens Wiklander          | ( ctx->total[1] <<  3 );
378817466cbSJens Wiklander     low  = ( ctx->total[0] <<  3 );
379817466cbSJens Wiklander 
380*039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE( low,  msglen, 0 );
381*039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
382817466cbSJens Wiklander 
383817466cbSJens Wiklander     last = ctx->total[0] & 0x3F;
384817466cbSJens Wiklander     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
385817466cbSJens Wiklander 
3863d3b0591SJens Wiklander     ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
3873d3b0591SJens Wiklander     if( ret != 0 )
3883d3b0591SJens Wiklander         return( ret );
3893d3b0591SJens Wiklander 
3903d3b0591SJens Wiklander     ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
3913d3b0591SJens Wiklander     if( ret != 0 )
3923d3b0591SJens Wiklander         return( ret );
393817466cbSJens Wiklander 
394*039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE( ctx->state[0], output,  0 );
395*039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE( ctx->state[1], output,  4 );
396*039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE( ctx->state[2], output,  8 );
397*039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
398*039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE( ctx->state[4], output, 16 );
3993d3b0591SJens Wiklander 
4003d3b0591SJens Wiklander     return( 0 );
401817466cbSJens Wiklander }
402817466cbSJens Wiklander 
4033d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED)
4043d3b0591SJens Wiklander void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
4053d3b0591SJens Wiklander                                unsigned char output[20] )
4063d3b0591SJens Wiklander {
4073d3b0591SJens Wiklander     mbedtls_ripemd160_finish_ret( ctx, output );
4083d3b0591SJens Wiklander }
4093d3b0591SJens Wiklander #endif
4103d3b0591SJens Wiklander 
4113d3b0591SJens Wiklander #endif /* ! MBEDTLS_RIPEMD160_ALT */
4123d3b0591SJens Wiklander 
413817466cbSJens Wiklander /*
414817466cbSJens Wiklander  * output = RIPEMD-160( input buffer )
415817466cbSJens Wiklander  */
4163d3b0591SJens Wiklander int mbedtls_ripemd160_ret( const unsigned char *input,
4173d3b0591SJens Wiklander                            size_t ilen,
418817466cbSJens Wiklander                            unsigned char output[20] )
419817466cbSJens Wiklander {
42011fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
421817466cbSJens Wiklander     mbedtls_ripemd160_context ctx;
422817466cbSJens Wiklander 
423817466cbSJens Wiklander     mbedtls_ripemd160_init( &ctx );
4243d3b0591SJens Wiklander 
4253d3b0591SJens Wiklander     if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
4263d3b0591SJens Wiklander         goto exit;
4273d3b0591SJens Wiklander 
4283d3b0591SJens Wiklander     if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
4293d3b0591SJens Wiklander         goto exit;
4303d3b0591SJens Wiklander 
4313d3b0591SJens Wiklander     if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
4323d3b0591SJens Wiklander         goto exit;
4333d3b0591SJens Wiklander 
4343d3b0591SJens Wiklander exit:
435817466cbSJens Wiklander     mbedtls_ripemd160_free( &ctx );
4363d3b0591SJens Wiklander 
4373d3b0591SJens Wiklander     return( ret );
438817466cbSJens Wiklander }
439817466cbSJens Wiklander 
4403d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED)
4413d3b0591SJens Wiklander void mbedtls_ripemd160( const unsigned char *input,
4423d3b0591SJens Wiklander                         size_t ilen,
4433d3b0591SJens Wiklander                         unsigned char output[20] )
4443d3b0591SJens Wiklander {
4453d3b0591SJens Wiklander     mbedtls_ripemd160_ret( input, ilen, output );
4463d3b0591SJens Wiklander }
4473d3b0591SJens Wiklander #endif
4483d3b0591SJens Wiklander 
449817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST)
450817466cbSJens Wiklander /*
451817466cbSJens Wiklander  * Test vectors from the RIPEMD-160 paper and
452817466cbSJens Wiklander  * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
453817466cbSJens Wiklander  */
454817466cbSJens Wiklander #define TESTS   8
4553d3b0591SJens Wiklander static const unsigned char ripemd160_test_str[TESTS][81] =
456817466cbSJens Wiklander {
4573d3b0591SJens Wiklander     { "" },
4583d3b0591SJens Wiklander     { "a" },
4593d3b0591SJens Wiklander     { "abc" },
4603d3b0591SJens Wiklander     { "message digest" },
4613d3b0591SJens Wiklander     { "abcdefghijklmnopqrstuvwxyz" },
4623d3b0591SJens Wiklander     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
4633d3b0591SJens Wiklander     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
46436905f94SGuido Vranken     { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
4653d3b0591SJens Wiklander };
4663d3b0591SJens Wiklander 
4673d3b0591SJens Wiklander static const size_t ripemd160_test_strlen[TESTS] =
4683d3b0591SJens Wiklander {
4693d3b0591SJens Wiklander     0, 1, 3, 14, 26, 56, 62, 80
470817466cbSJens Wiklander };
471817466cbSJens Wiklander 
472817466cbSJens Wiklander static const unsigned char ripemd160_test_md[TESTS][20] =
473817466cbSJens Wiklander {
474817466cbSJens Wiklander     { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
475817466cbSJens Wiklander       0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
476817466cbSJens Wiklander     { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
477817466cbSJens Wiklander       0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
478817466cbSJens Wiklander     { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
479817466cbSJens Wiklander       0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
480817466cbSJens Wiklander     { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
481817466cbSJens Wiklander       0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
482817466cbSJens Wiklander     { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
483817466cbSJens Wiklander       0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
484817466cbSJens Wiklander     { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
485817466cbSJens Wiklander       0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
486817466cbSJens Wiklander     { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
487817466cbSJens Wiklander       0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
488817466cbSJens Wiklander     { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
489817466cbSJens Wiklander       0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
490817466cbSJens Wiklander };
491817466cbSJens Wiklander 
492817466cbSJens Wiklander /*
493817466cbSJens Wiklander  * Checkup routine
494817466cbSJens Wiklander  */
495817466cbSJens Wiklander int mbedtls_ripemd160_self_test( int verbose )
496817466cbSJens Wiklander {
4973d3b0591SJens Wiklander     int i, ret = 0;
498817466cbSJens Wiklander     unsigned char output[20];
499817466cbSJens Wiklander 
500817466cbSJens Wiklander     memset( output, 0, sizeof output );
501817466cbSJens Wiklander 
502817466cbSJens Wiklander     for( i = 0; i < TESTS; i++ )
503817466cbSJens Wiklander     {
504817466cbSJens Wiklander         if( verbose != 0 )
505817466cbSJens Wiklander             mbedtls_printf( "  RIPEMD-160 test #%d: ", i + 1 );
506817466cbSJens Wiklander 
5073d3b0591SJens Wiklander         ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
5083d3b0591SJens Wiklander                                      ripemd160_test_strlen[i], output );
5093d3b0591SJens Wiklander         if( ret != 0 )
5103d3b0591SJens Wiklander             goto fail;
511817466cbSJens Wiklander 
512817466cbSJens Wiklander         if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
513817466cbSJens Wiklander         {
5143d3b0591SJens Wiklander             ret = 1;
5153d3b0591SJens Wiklander             goto fail;
516817466cbSJens Wiklander         }
517817466cbSJens Wiklander 
518817466cbSJens Wiklander         if( verbose != 0 )
519817466cbSJens Wiklander             mbedtls_printf( "passed\n" );
520817466cbSJens Wiklander     }
521817466cbSJens Wiklander 
522817466cbSJens Wiklander     if( verbose != 0 )
523817466cbSJens Wiklander         mbedtls_printf( "\n" );
524817466cbSJens Wiklander 
525817466cbSJens Wiklander     return( 0 );
5263d3b0591SJens Wiklander 
5273d3b0591SJens Wiklander fail:
5283d3b0591SJens Wiklander     if( verbose != 0 )
5293d3b0591SJens Wiklander         mbedtls_printf( "failed\n" );
5303d3b0591SJens Wiklander 
5313d3b0591SJens Wiklander     return( ret );
532817466cbSJens Wiklander }
533817466cbSJens Wiklander 
534817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */
535817466cbSJens Wiklander 
536817466cbSJens Wiklander #endif /* MBEDTLS_RIPEMD160_C */
537