[MBEDTLS]
[reactos.git] / reactos / dll / 3rdparty / mbedtls / ripemd160.c
1 /*
2 * RIPE MD-160 implementation
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23
24 /*
25 * The RIPEMD-160 algorithm was designed by RIPE in 1996
26 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
27 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
28 */
29
30 #if !defined(MBEDTLS_CONFIG_FILE)
31 #include "mbedtls/config.h"
32 #else
33 #include MBEDTLS_CONFIG_FILE
34 #endif
35
36 #if defined(MBEDTLS_RIPEMD160_C)
37
38 #include "mbedtls/ripemd160.h"
39
40 #include <string.h>
41
42 #if defined(MBEDTLS_SELF_TEST)
43 #if defined(MBEDTLS_PLATFORM_C)
44 #include "mbedtls/platform.h"
45 #else
46 #include <stdio.h>
47 #define mbedtls_printf printf
48 #endif /* MBEDTLS_PLATFORM_C */
49 #endif /* MBEDTLS_SELF_TEST */
50
51 /*
52 * 32-bit integer manipulation macros (little endian)
53 */
54 #ifndef GET_UINT32_LE
55 #define GET_UINT32_LE(n,b,i) \
56 { \
57 (n) = ( (uint32_t) (b)[(i) ] ) \
58 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
59 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
60 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
61 }
62 #endif
63
64 #ifndef PUT_UINT32_LE
65 #define PUT_UINT32_LE(n,b,i) \
66 { \
67 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
68 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
69 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
70 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
71 }
72 #endif
73
74 /* Implementation that should never be optimized out by the compiler */
75 static void mbedtls_zeroize( void *v, size_t n ) {
76 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
77 }
78
79 void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
80 {
81 memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
82 }
83
84 void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
85 {
86 if( ctx == NULL )
87 return;
88
89 mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
90 }
91
92 void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
93 const mbedtls_ripemd160_context *src )
94 {
95 *dst = *src;
96 }
97
98 /*
99 * RIPEMD-160 context setup
100 */
101 void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
102 {
103 ctx->total[0] = 0;
104 ctx->total[1] = 0;
105
106 ctx->state[0] = 0x67452301;
107 ctx->state[1] = 0xEFCDAB89;
108 ctx->state[2] = 0x98BADCFE;
109 ctx->state[3] = 0x10325476;
110 ctx->state[4] = 0xC3D2E1F0;
111 }
112
113 #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
114 /*
115 * Process one block
116 */
117 void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] )
118 {
119 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
120
121 GET_UINT32_LE( X[ 0], data, 0 );
122 GET_UINT32_LE( X[ 1], data, 4 );
123 GET_UINT32_LE( X[ 2], data, 8 );
124 GET_UINT32_LE( X[ 3], data, 12 );
125 GET_UINT32_LE( X[ 4], data, 16 );
126 GET_UINT32_LE( X[ 5], data, 20 );
127 GET_UINT32_LE( X[ 6], data, 24 );
128 GET_UINT32_LE( X[ 7], data, 28 );
129 GET_UINT32_LE( X[ 8], data, 32 );
130 GET_UINT32_LE( X[ 9], data, 36 );
131 GET_UINT32_LE( X[10], data, 40 );
132 GET_UINT32_LE( X[11], data, 44 );
133 GET_UINT32_LE( X[12], data, 48 );
134 GET_UINT32_LE( X[13], data, 52 );
135 GET_UINT32_LE( X[14], data, 56 );
136 GET_UINT32_LE( X[15], data, 60 );
137
138 A = Ap = ctx->state[0];
139 B = Bp = ctx->state[1];
140 C = Cp = ctx->state[2];
141 D = Dp = ctx->state[3];
142 E = Ep = ctx->state[4];
143
144 #define F1( x, y, z ) ( x ^ y ^ z )
145 #define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
146 #define F3( x, y, z ) ( ( x | ~y ) ^ z )
147 #define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
148 #define F5( x, y, z ) ( x ^ ( y | ~z ) )
149
150 #define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
151
152 #define P( a, b, c, d, e, r, s, f, k ) \
153 a += f( b, c, d ) + X[r] + k; \
154 a = S( a, s ) + e; \
155 c = S( c, 10 );
156
157 #define P2( a, b, c, d, e, r, s, rp, sp ) \
158 P( a, b, c, d, e, r, s, F, K ); \
159 P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
160
161 #define F F1
162 #define K 0x00000000
163 #define Fp F5
164 #define Kp 0x50A28BE6
165 P2( A, B, C, D, E, 0, 11, 5, 8 );
166 P2( E, A, B, C, D, 1, 14, 14, 9 );
167 P2( D, E, A, B, C, 2, 15, 7, 9 );
168 P2( C, D, E, A, B, 3, 12, 0, 11 );
169 P2( B, C, D, E, A, 4, 5, 9, 13 );
170 P2( A, B, C, D, E, 5, 8, 2, 15 );
171 P2( E, A, B, C, D, 6, 7, 11, 15 );
172 P2( D, E, A, B, C, 7, 9, 4, 5 );
173 P2( C, D, E, A, B, 8, 11, 13, 7 );
174 P2( B, C, D, E, A, 9, 13, 6, 7 );
175 P2( A, B, C, D, E, 10, 14, 15, 8 );
176 P2( E, A, B, C, D, 11, 15, 8, 11 );
177 P2( D, E, A, B, C, 12, 6, 1, 14 );
178 P2( C, D, E, A, B, 13, 7, 10, 14 );
179 P2( B, C, D, E, A, 14, 9, 3, 12 );
180 P2( A, B, C, D, E, 15, 8, 12, 6 );
181 #undef F
182 #undef K
183 #undef Fp
184 #undef Kp
185
186 #define F F2
187 #define K 0x5A827999
188 #define Fp F4
189 #define Kp 0x5C4DD124
190 P2( E, A, B, C, D, 7, 7, 6, 9 );
191 P2( D, E, A, B, C, 4, 6, 11, 13 );
192 P2( C, D, E, A, B, 13, 8, 3, 15 );
193 P2( B, C, D, E, A, 1, 13, 7, 7 );
194 P2( A, B, C, D, E, 10, 11, 0, 12 );
195 P2( E, A, B, C, D, 6, 9, 13, 8 );
196 P2( D, E, A, B, C, 15, 7, 5, 9 );
197 P2( C, D, E, A, B, 3, 15, 10, 11 );
198 P2( B, C, D, E, A, 12, 7, 14, 7 );
199 P2( A, B, C, D, E, 0, 12, 15, 7 );
200 P2( E, A, B, C, D, 9, 15, 8, 12 );
201 P2( D, E, A, B, C, 5, 9, 12, 7 );
202 P2( C, D, E, A, B, 2, 11, 4, 6 );
203 P2( B, C, D, E, A, 14, 7, 9, 15 );
204 P2( A, B, C, D, E, 11, 13, 1, 13 );
205 P2( E, A, B, C, D, 8, 12, 2, 11 );
206 #undef F
207 #undef K
208 #undef Fp
209 #undef Kp
210
211 #define F F3
212 #define K 0x6ED9EBA1
213 #define Fp F3
214 #define Kp 0x6D703EF3
215 P2( D, E, A, B, C, 3, 11, 15, 9 );
216 P2( C, D, E, A, B, 10, 13, 5, 7 );
217 P2( B, C, D, E, A, 14, 6, 1, 15 );
218 P2( A, B, C, D, E, 4, 7, 3, 11 );
219 P2( E, A, B, C, D, 9, 14, 7, 8 );
220 P2( D, E, A, B, C, 15, 9, 14, 6 );
221 P2( C, D, E, A, B, 8, 13, 6, 6 );
222 P2( B, C, D, E, A, 1, 15, 9, 14 );
223 P2( A, B, C, D, E, 2, 14, 11, 12 );
224 P2( E, A, B, C, D, 7, 8, 8, 13 );
225 P2( D, E, A, B, C, 0, 13, 12, 5 );
226 P2( C, D, E, A, B, 6, 6, 2, 14 );
227 P2( B, C, D, E, A, 13, 5, 10, 13 );
228 P2( A, B, C, D, E, 11, 12, 0, 13 );
229 P2( E, A, B, C, D, 5, 7, 4, 7 );
230 P2( D, E, A, B, C, 12, 5, 13, 5 );
231 #undef F
232 #undef K
233 #undef Fp
234 #undef Kp
235
236 #define F F4
237 #define K 0x8F1BBCDC
238 #define Fp F2
239 #define Kp 0x7A6D76E9
240 P2( C, D, E, A, B, 1, 11, 8, 15 );
241 P2( B, C, D, E, A, 9, 12, 6, 5 );
242 P2( A, B, C, D, E, 11, 14, 4, 8 );
243 P2( E, A, B, C, D, 10, 15, 1, 11 );
244 P2( D, E, A, B, C, 0, 14, 3, 14 );
245 P2( C, D, E, A, B, 8, 15, 11, 14 );
246 P2( B, C, D, E, A, 12, 9, 15, 6 );
247 P2( A, B, C, D, E, 4, 8, 0, 14 );
248 P2( E, A, B, C, D, 13, 9, 5, 6 );
249 P2( D, E, A, B, C, 3, 14, 12, 9 );
250 P2( C, D, E, A, B, 7, 5, 2, 12 );
251 P2( B, C, D, E, A, 15, 6, 13, 9 );
252 P2( A, B, C, D, E, 14, 8, 9, 12 );
253 P2( E, A, B, C, D, 5, 6, 7, 5 );
254 P2( D, E, A, B, C, 6, 5, 10, 15 );
255 P2( C, D, E, A, B, 2, 12, 14, 8 );
256 #undef F
257 #undef K
258 #undef Fp
259 #undef Kp
260
261 #define F F5
262 #define K 0xA953FD4E
263 #define Fp F1
264 #define Kp 0x00000000
265 P2( B, C, D, E, A, 4, 9, 12, 8 );
266 P2( A, B, C, D, E, 0, 15, 15, 5 );
267 P2( E, A, B, C, D, 5, 5, 10, 12 );
268 P2( D, E, A, B, C, 9, 11, 4, 9 );
269 P2( C, D, E, A, B, 7, 6, 1, 12 );
270 P2( B, C, D, E, A, 12, 8, 5, 5 );
271 P2( A, B, C, D, E, 2, 13, 8, 14 );
272 P2( E, A, B, C, D, 10, 12, 7, 6 );
273 P2( D, E, A, B, C, 14, 5, 6, 8 );
274 P2( C, D, E, A, B, 1, 12, 2, 13 );
275 P2( B, C, D, E, A, 3, 13, 13, 6 );
276 P2( A, B, C, D, E, 8, 14, 14, 5 );
277 P2( E, A, B, C, D, 11, 11, 0, 15 );
278 P2( D, E, A, B, C, 6, 8, 3, 13 );
279 P2( C, D, E, A, B, 15, 5, 9, 11 );
280 P2( B, C, D, E, A, 13, 6, 11, 11 );
281 #undef F
282 #undef K
283 #undef Fp
284 #undef Kp
285
286 C = ctx->state[1] + C + Dp;
287 ctx->state[1] = ctx->state[2] + D + Ep;
288 ctx->state[2] = ctx->state[3] + E + Ap;
289 ctx->state[3] = ctx->state[4] + A + Bp;
290 ctx->state[4] = ctx->state[0] + B + Cp;
291 ctx->state[0] = C;
292 }
293 #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
294
295 /*
296 * RIPEMD-160 process buffer
297 */
298 void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
299 const unsigned char *input, size_t ilen )
300 {
301 size_t fill;
302 uint32_t left;
303
304 if( ilen == 0 )
305 return;
306
307 left = ctx->total[0] & 0x3F;
308 fill = 64 - left;
309
310 ctx->total[0] += (uint32_t) ilen;
311 ctx->total[0] &= 0xFFFFFFFF;
312
313 if( ctx->total[0] < (uint32_t) ilen )
314 ctx->total[1]++;
315
316 if( left && ilen >= fill )
317 {
318 memcpy( (void *) (ctx->buffer + left), input, fill );
319 mbedtls_ripemd160_process( ctx, ctx->buffer );
320 input += fill;
321 ilen -= fill;
322 left = 0;
323 }
324
325 while( ilen >= 64 )
326 {
327 mbedtls_ripemd160_process( ctx, input );
328 input += 64;
329 ilen -= 64;
330 }
331
332 if( ilen > 0 )
333 {
334 memcpy( (void *) (ctx->buffer + left), input, ilen );
335 }
336 }
337
338 static const unsigned char ripemd160_padding[64] =
339 {
340 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
341 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
342 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
343 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
344 };
345
346 /*
347 * RIPEMD-160 final digest
348 */
349 void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char output[20] )
350 {
351 uint32_t last, padn;
352 uint32_t high, low;
353 unsigned char msglen[8];
354
355 high = ( ctx->total[0] >> 29 )
356 | ( ctx->total[1] << 3 );
357 low = ( ctx->total[0] << 3 );
358
359 PUT_UINT32_LE( low, msglen, 0 );
360 PUT_UINT32_LE( high, msglen, 4 );
361
362 last = ctx->total[0] & 0x3F;
363 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
364
365 mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
366 mbedtls_ripemd160_update( ctx, msglen, 8 );
367
368 PUT_UINT32_LE( ctx->state[0], output, 0 );
369 PUT_UINT32_LE( ctx->state[1], output, 4 );
370 PUT_UINT32_LE( ctx->state[2], output, 8 );
371 PUT_UINT32_LE( ctx->state[3], output, 12 );
372 PUT_UINT32_LE( ctx->state[4], output, 16 );
373 }
374
375 /*
376 * output = RIPEMD-160( input buffer )
377 */
378 void mbedtls_ripemd160( const unsigned char *input, size_t ilen,
379 unsigned char output[20] )
380 {
381 mbedtls_ripemd160_context ctx;
382
383 mbedtls_ripemd160_init( &ctx );
384 mbedtls_ripemd160_starts( &ctx );
385 mbedtls_ripemd160_update( &ctx, input, ilen );
386 mbedtls_ripemd160_finish( &ctx, output );
387 mbedtls_ripemd160_free( &ctx );
388 }
389
390 #if defined(MBEDTLS_SELF_TEST)
391 /*
392 * Test vectors from the RIPEMD-160 paper and
393 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
394 */
395 #define TESTS 8
396 #define KEYS 2
397 static const char *ripemd160_test_input[TESTS] =
398 {
399 "",
400 "a",
401 "abc",
402 "message digest",
403 "abcdefghijklmnopqrstuvwxyz",
404 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
405 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
406 "1234567890123456789012345678901234567890"
407 "1234567890123456789012345678901234567890",
408 };
409
410 static const unsigned char ripemd160_test_md[TESTS][20] =
411 {
412 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
413 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
414 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
415 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
416 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
417 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
418 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
419 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
420 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
421 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
422 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
423 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
424 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
425 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
426 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
427 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
428 };
429
430 /*
431 * Checkup routine
432 */
433 int mbedtls_ripemd160_self_test( int verbose )
434 {
435 int i;
436 unsigned char output[20];
437
438 memset( output, 0, sizeof output );
439
440 for( i = 0; i < TESTS; i++ )
441 {
442 if( verbose != 0 )
443 mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
444
445 mbedtls_ripemd160( (const unsigned char *) ripemd160_test_input[i],
446 strlen( ripemd160_test_input[i] ),
447 output );
448
449 if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
450 {
451 if( verbose != 0 )
452 mbedtls_printf( "failed\n" );
453
454 return( 1 );
455 }
456
457 if( verbose != 0 )
458 mbedtls_printf( "passed\n" );
459 }
460
461 if( verbose != 0 )
462 mbedtls_printf( "\n" );
463
464 return( 0 );
465 }
466
467 #endif /* MBEDTLS_SELF_TEST */
468
469 #endif /* MBEDTLS_RIPEMD160_C */