blob: 41d838722627a41bbe41e962880a8200030f2475 [file] [log] [blame]
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +01001/*
2 * RIPE MD-160 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010018 */
19
20/*
21 * The RIPEMD-160 algorithm was designed by RIPE in 1996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010023 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/ripemd160.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000032#include "mbedtls/error.h"
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_SELF_TEST)
37#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010039#else
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_printf printf
42#endif /* MBEDTLS_PLATFORM_C */
43#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Gilles Peskine342d9282018-01-23 18:21:21 +010045#if !defined(MBEDTLS_RIPEMD160_ALT)
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020048{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020050}
51
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020053{
54 if( ctx == NULL )
55 return;
56
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050057 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020058}
59
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020060void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
61 const mbedtls_ripemd160_context *src )
62{
63 *dst = *src;
64}
65
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010066/*
Paul Bakker61b699e2014-01-22 13:35:29 +010067 * RIPEMD-160 context setup
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010068 */
TRodziewicz26371e42021-06-08 16:45:41 +020069int mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010070{
71 ctx->total[0] = 0;
72 ctx->total[1] = 0;
73
74 ctx->state[0] = 0x67452301;
75 ctx->state[1] = 0xEFCDAB89;
76 ctx->state[2] = 0x98BADCFE;
77 ctx->state[3] = 0x10325476;
78 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +010079
80 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010081}
82
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +010084/*
85 * Process one block
86 */
Andres Amaya Garciacccfe082017-06-28 10:36:39 +010087int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
88 const unsigned char data[64] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010089{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020090 struct
91 {
92 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
93 } local;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +010094
Joe Subbiani6a506312021-07-07 16:56:29 +010095 local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
96 local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
97 local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
98 local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
99 local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
100 local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
101 local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
102 local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
103 local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
104 local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
105 local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
106 local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
107 local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
108 local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
109 local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
110 local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100111
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200112 local.A = local.Ap = ctx->state[0];
113 local.B = local.Bp = ctx->state[1];
114 local.C = local.Cp = ctx->state[2];
115 local.D = local.Dp = ctx->state[3];
116 local.E = local.Ep = ctx->state[4];
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100117
Hanno Becker1eeca412018-10-15 12:01:35 +0100118#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
119#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
120#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) )
121#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) )
122#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100123
Hanno Becker1eeca412018-10-15 12:01:35 +0100124#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100125
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200126#define P( a, b, c, d, e, r, s, f, k ) \
127 do \
128 { \
129 (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
130 (a) = S( (a), (s) ) + (e); \
131 (c) = S( (c), 10 ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100132 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100133
Hanno Becker1eeca412018-10-15 12:01:35 +0100134#define P2( a, b, c, d, e, r, s, rp, sp ) \
135 do \
136 { \
137 P( (a), (b), (c), (d), (e), (r), (s), F, K ); \
138 P( a ## p, b ## p, c ## p, d ## p, e ## p, \
139 (rp), (sp), Fp, Kp ); \
140 } while( 0 )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100141
142#define F F1
143#define K 0x00000000
144#define Fp F5
145#define Kp 0x50A28BE6
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200146 P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
147 P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
148 P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
149 P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
150 P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
151 P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
152 P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
153 P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
154 P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
155 P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
156 P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
157 P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
158 P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
159 P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
160 P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
161 P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100162#undef F
163#undef K
164#undef Fp
165#undef Kp
166
167#define F F2
168#define K 0x5A827999
169#define Fp F4
170#define Kp 0x5C4DD124
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200171 P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
172 P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
173 P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
174 P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
175 P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
176 P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
177 P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
178 P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
179 P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
180 P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
181 P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
182 P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
183 P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
184 P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
185 P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
186 P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100187#undef F
188#undef K
189#undef Fp
190#undef Kp
191
192#define F F3
193#define K 0x6ED9EBA1
194#define Fp F3
195#define Kp 0x6D703EF3
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200196 P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
197 P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
198 P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
199 P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
200 P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
201 P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
202 P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
203 P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
204 P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
205 P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
206 P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
207 P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
208 P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
209 P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
210 P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
211 P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100212#undef F
213#undef K
214#undef Fp
215#undef Kp
216
217#define F F4
218#define K 0x8F1BBCDC
219#define Fp F2
220#define Kp 0x7A6D76E9
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200221 P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
222 P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
223 P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
224 P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
225 P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
226 P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
227 P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
228 P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
229 P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
230 P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
231 P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
232 P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
233 P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
234 P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
235 P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
236 P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100237#undef F
238#undef K
239#undef Fp
240#undef Kp
241
242#define F F5
243#define K 0xA953FD4E
244#define Fp F1
245#define Kp 0x00000000
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200246 P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
247 P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
248 P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
249 P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
250 P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
251 P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
252 P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
253 P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
254 P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
255 P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
256 P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
257 P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
258 P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
259 P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
260 P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
261 P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100262#undef F
263#undef K
264#undef Fp
265#undef Kp
266
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200267 local.C = ctx->state[1] + local.C + local.Dp;
268 ctx->state[1] = ctx->state[2] + local.D + local.Ep;
269 ctx->state[2] = ctx->state[3] + local.E + local.Ap;
270 ctx->state[3] = ctx->state[4] + local.A + local.Bp;
271 ctx->state[4] = ctx->state[0] + local.B + local.Cp;
272 ctx->state[0] = local.C;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100273
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200274 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200275 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100276
277 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100278}
Jaeden Amero041039f2018-02-19 15:28:08 +0000279
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100281
282/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100283 * RIPEMD-160 process buffer
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100284 */
TRodziewicz26371e42021-06-08 16:45:41 +0200285int mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100286 const unsigned char *input,
287 size_t ilen )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100288{
Janos Follath24eed8d2019-11-22 13:21:35 +0000289 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100290 size_t fill;
291 uint32_t left;
292
Brian White12895d12014-04-11 11:29:42 -0400293 if( ilen == 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100294 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100295
296 left = ctx->total[0] & 0x3F;
297 fill = 64 - left;
298
299 ctx->total[0] += (uint32_t) ilen;
300 ctx->total[0] &= 0xFFFFFFFF;
301
302 if( ctx->total[0] < (uint32_t) ilen )
303 ctx->total[1]++;
304
305 if( left && ilen >= fill )
306 {
307 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100308
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100309 if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100310 return( ret );
311
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100312 input += fill;
313 ilen -= fill;
314 left = 0;
315 }
316
317 while( ilen >= 64 )
318 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100319 if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100320 return( ret );
321
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100322 input += 64;
323 ilen -= 64;
324 }
325
326 if( ilen > 0 )
327 {
328 memcpy( (void *) (ctx->buffer + left), input, ilen );
329 }
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100330
331 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100332}
333
Paul Bakker61b699e2014-01-22 13:35:29 +0100334static const unsigned char ripemd160_padding[64] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100335{
336 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
339 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
340};
341
342/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100343 * RIPEMD-160 final digest
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100344 */
TRodziewicz26371e42021-06-08 16:45:41 +0200345int mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100346 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100347{
Janos Follath24eed8d2019-11-22 13:21:35 +0000348 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100349 uint32_t last, padn;
350 uint32_t high, low;
351 unsigned char msglen[8];
352
353 high = ( ctx->total[0] >> 29 )
354 | ( ctx->total[1] << 3 );
355 low = ( ctx->total[0] << 3 );
356
Joe Subbiani5ecac212021-06-24 13:00:03 +0100357 MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
358 MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100359
360 last = ctx->total[0] & 0x3F;
361 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
362
TRodziewicz26371e42021-06-08 16:45:41 +0200363 ret = mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100364 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100365 return( ret );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100366
TRodziewicz26371e42021-06-08 16:45:41 +0200367 ret = mbedtls_ripemd160_update( ctx, msglen, 8 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100368 if( ret != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100369 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100370
Joe Subbiani5ecac212021-06-24 13:00:03 +0100371 MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
372 MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
373 MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
374 MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
375 MBEDTLS_PUT_UINT32_LE( ctx->state[4], output, 16 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100376
377 return( 0 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100378}
379
Gilles Peskine342d9282018-01-23 18:21:21 +0100380#endif /* ! MBEDTLS_RIPEMD160_ALT */
381
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100382/*
Paul Bakker61b699e2014-01-22 13:35:29 +0100383 * output = RIPEMD-160( input buffer )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100384 */
TRodziewicz26371e42021-06-08 16:45:41 +0200385int mbedtls_ripemd160( const unsigned char *input,
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100386 size_t ilen,
387 unsigned char output[20] )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100388{
Janos Follath24eed8d2019-11-22 13:21:35 +0000389 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 mbedtls_ripemd160_context ctx;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392 mbedtls_ripemd160_init( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100393
TRodziewicz26371e42021-06-08 16:45:41 +0200394 if( ( ret = mbedtls_ripemd160_starts( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100395 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100396
TRodziewicz26371e42021-06-08 16:45:41 +0200397 if( ( ret = mbedtls_ripemd160_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100398 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100399
TRodziewicz26371e42021-06-08 16:45:41 +0200400 if( ( ret = mbedtls_ripemd160_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100401 goto exit;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100402
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100403exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 mbedtls_ripemd160_free( &ctx );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100405
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100406 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100407}
408
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100410/*
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100411 * Test vectors from the RIPEMD-160 paper and
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100413 */
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100414#define TESTS 8
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100415static const unsigned char ripemd160_test_str[TESTS][81] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100416{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100417 { "" },
418 { "a" },
419 { "abc" },
420 { "message digest" },
421 { "abcdefghijklmnopqrstuvwxyz" },
422 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
423 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200424 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100425};
426
427static const size_t ripemd160_test_strlen[TESTS] =
428{
429 0, 1, 3, 14, 26, 56, 62, 80
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100430};
431
Paul Bakker61b699e2014-01-22 13:35:29 +0100432static const unsigned char ripemd160_test_md[TESTS][20] =
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100433{
434 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
435 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
436 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
437 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
438 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
439 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
440 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
441 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
442 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
443 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
444 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
445 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
446 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
447 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
448 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
449 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
450};
451
452/*
453 * Checkup routine
454 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455int mbedtls_ripemd160_self_test( int verbose )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100456{
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100457 int i, ret = 0;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100458 unsigned char output[20];
459
460 memset( output, 0, sizeof output );
461
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100462 for( i = 0; i < TESTS; i++ )
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100463 {
464 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100466
TRodziewicz26371e42021-06-08 16:45:41 +0200467 ret = mbedtls_ripemd160( ripemd160_test_str[i],
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100468 ripemd160_test_strlen[i], output );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100469 if( ret != 0 )
470 goto fail;
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100471
Paul Bakker61b699e2014-01-22 13:35:29 +0100472 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100473 {
474 ret = 1;
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100475 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100476 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100477
478 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnardff40c3a2014-01-17 19:49:15 +0100480 }
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100481
Paul Bakker4400ecc2016-07-19 14:41:43 +0100482 if( verbose != 0 )
483 mbedtls_printf( "\n" );
484
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100485 return( 0 );
Andres Amaya Garciab1a8bf92017-05-02 10:59:46 +0100486
487fail:
488 if( verbose != 0 )
489 mbedtls_printf( "failed\n" );
490
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100491 return( ret );
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100492}
493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnardcab4a882014-01-17 12:42:35 +0100495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#endif /* MBEDTLS_RIPEMD160_C */