Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / mbedtls / repo / library / ripemd160.c
1 /*
2  *  RIPE MD-160 implementation
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  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.
18  *
19  *  This file is part of mbed TLS (https://tls.mbed.org)
20  */
21
22 /*
23  *  The RIPEMD-160 algorithm was designed by RIPE in 1996
24  *  http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
25  *  http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
26  */
27
28 #if !defined(MBEDTLS_CONFIG_FILE)
29 #include "mbedtls/config.h"
30 #else
31 #include MBEDTLS_CONFIG_FILE
32 #endif
33
34 #if defined(MBEDTLS_RIPEMD160_C)
35
36 #include "mbedtls/ripemd160.h"
37 #include "mbedtls/platform_util.h"
38
39 #include <string.h>
40
41 #if defined(MBEDTLS_SELF_TEST)
42 #if defined(MBEDTLS_PLATFORM_C)
43 #include "mbedtls/platform.h"
44 #else
45 #include <stdio.h>
46 #define mbedtls_printf printf
47 #endif /* MBEDTLS_PLATFORM_C */
48 #endif /* MBEDTLS_SELF_TEST */
49
50 #if !defined(MBEDTLS_RIPEMD160_ALT)
51
52 /*
53  * 32-bit integer manipulation macros (little endian)
54  */
55 #ifndef GET_UINT32_LE
56 #define GET_UINT32_LE(n,b,i)                            \
57 {                                                       \
58     (n) = ( (uint32_t) (b)[(i)    ]       )             \
59         | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
60         | ( (uint32_t) (b)[(i) + 2] << 16 )             \
61         | ( (uint32_t) (b)[(i) + 3] << 24 );            \
62 }
63 #endif
64
65 #ifndef PUT_UINT32_LE
66 #define PUT_UINT32_LE(n,b,i)                                    \
67 {                                                               \
68     (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
69     (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
70     (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
71     (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
72 }
73 #endif
74
75 void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
76 {
77     memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
78 }
79
80 void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
81 {
82     if( ctx == NULL )
83         return;
84
85     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
86 }
87
88 void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
89                         const mbedtls_ripemd160_context *src )
90 {
91     *dst = *src;
92 }
93
94 /*
95  * RIPEMD-160 context setup
96  */
97 int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
98 {
99     ctx->total[0] = 0;
100     ctx->total[1] = 0;
101
102     ctx->state[0] = 0x67452301;
103     ctx->state[1] = 0xEFCDAB89;
104     ctx->state[2] = 0x98BADCFE;
105     ctx->state[3] = 0x10325476;
106     ctx->state[4] = 0xC3D2E1F0;
107
108     return( 0 );
109 }
110
111 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
112 void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
113 {
114     mbedtls_ripemd160_starts_ret( ctx );
115 }
116 #endif
117
118 #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
119 /*
120  * Process one block
121  */
122 int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
123                                         const unsigned char data[64] )
124 {
125     uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
126
127     GET_UINT32_LE( X[ 0], data,  0 );
128     GET_UINT32_LE( X[ 1], data,  4 );
129     GET_UINT32_LE( X[ 2], data,  8 );
130     GET_UINT32_LE( X[ 3], data, 12 );
131     GET_UINT32_LE( X[ 4], data, 16 );
132     GET_UINT32_LE( X[ 5], data, 20 );
133     GET_UINT32_LE( X[ 6], data, 24 );
134     GET_UINT32_LE( X[ 7], data, 28 );
135     GET_UINT32_LE( X[ 8], data, 32 );
136     GET_UINT32_LE( X[ 9], data, 36 );
137     GET_UINT32_LE( X[10], data, 40 );
138     GET_UINT32_LE( X[11], data, 44 );
139     GET_UINT32_LE( X[12], data, 48 );
140     GET_UINT32_LE( X[13], data, 52 );
141     GET_UINT32_LE( X[14], data, 56 );
142     GET_UINT32_LE( X[15], data, 60 );
143
144     A = Ap = ctx->state[0];
145     B = Bp = ctx->state[1];
146     C = Cp = ctx->state[2];
147     D = Dp = ctx->state[3];
148     E = Ep = ctx->state[4];
149
150 #define F1( x, y, z )   ( (x) ^ (y) ^ (z) )
151 #define F2( x, y, z )   ( ( (x) & (y) ) | ( ~(x) & (z) ) )
152 #define F3( x, y, z )   ( ( (x) | ~(y) ) ^ (z) )
153 #define F4( x, y, z )   ( ( (x) & (z) ) | ( (y) & ~(z) ) )
154 #define F5( x, y, z )   ( (x) ^ ( (y) | ~(z) ) )
155
156 #define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
157
158 #define P( a, b, c, d, e, r, s, f, k )                \
159     do                                                \
160     {                                                 \
161         (a) += f( (b), (c), (d) ) + X[r] + (k);       \
162         (a) = S( (a), (s) ) + (e);                    \
163         (c) = S( (c), 10 );                           \
164     } while( 0 )
165
166 #define P2( a, b, c, d, e, r, s, rp, sp )                               \
167     do                                                                  \
168     {                                                                   \
169         P( (a), (b), (c), (d), (e), (r), (s), F, K );                   \
170         P( a ## p, b ## p, c ## p, d ## p, e ## p,                      \
171            (rp), (sp), Fp, Kp );                                        \
172     } while( 0 )
173
174 #define F   F1
175 #define K   0x00000000
176 #define Fp  F5
177 #define Kp  0x50A28BE6
178     P2( A, B, C, D, E,  0, 11,  5,  8 );
179     P2( E, A, B, C, D,  1, 14, 14,  9 );
180     P2( D, E, A, B, C,  2, 15,  7,  9 );
181     P2( C, D, E, A, B,  3, 12,  0, 11 );
182     P2( B, C, D, E, A,  4,  5,  9, 13 );
183     P2( A, B, C, D, E,  5,  8,  2, 15 );
184     P2( E, A, B, C, D,  6,  7, 11, 15 );
185     P2( D, E, A, B, C,  7,  9,  4,  5 );
186     P2( C, D, E, A, B,  8, 11, 13,  7 );
187     P2( B, C, D, E, A,  9, 13,  6,  7 );
188     P2( A, B, C, D, E, 10, 14, 15,  8 );
189     P2( E, A, B, C, D, 11, 15,  8, 11 );
190     P2( D, E, A, B, C, 12,  6,  1, 14 );
191     P2( C, D, E, A, B, 13,  7, 10, 14 );
192     P2( B, C, D, E, A, 14,  9,  3, 12 );
193     P2( A, B, C, D, E, 15,  8, 12,  6 );
194 #undef F
195 #undef K
196 #undef Fp
197 #undef Kp
198
199 #define F   F2
200 #define K   0x5A827999
201 #define Fp  F4
202 #define Kp  0x5C4DD124
203     P2( E, A, B, C, D,  7,  7,  6,  9 );
204     P2( D, E, A, B, C,  4,  6, 11, 13 );
205     P2( C, D, E, A, B, 13,  8,  3, 15 );
206     P2( B, C, D, E, A,  1, 13,  7,  7 );
207     P2( A, B, C, D, E, 10, 11,  0, 12 );
208     P2( E, A, B, C, D,  6,  9, 13,  8 );
209     P2( D, E, A, B, C, 15,  7,  5,  9 );
210     P2( C, D, E, A, B,  3, 15, 10, 11 );
211     P2( B, C, D, E, A, 12,  7, 14,  7 );
212     P2( A, B, C, D, E,  0, 12, 15,  7 );
213     P2( E, A, B, C, D,  9, 15,  8, 12 );
214     P2( D, E, A, B, C,  5,  9, 12,  7 );
215     P2( C, D, E, A, B,  2, 11,  4,  6 );
216     P2( B, C, D, E, A, 14,  7,  9, 15 );
217     P2( A, B, C, D, E, 11, 13,  1, 13 );
218     P2( E, A, B, C, D,  8, 12,  2, 11 );
219 #undef F
220 #undef K
221 #undef Fp
222 #undef Kp
223
224 #define F   F3
225 #define K   0x6ED9EBA1
226 #define Fp  F3
227 #define Kp  0x6D703EF3
228     P2( D, E, A, B, C,  3, 11, 15,  9 );
229     P2( C, D, E, A, B, 10, 13,  5,  7 );
230     P2( B, C, D, E, A, 14,  6,  1, 15 );
231     P2( A, B, C, D, E,  4,  7,  3, 11 );
232     P2( E, A, B, C, D,  9, 14,  7,  8 );
233     P2( D, E, A, B, C, 15,  9, 14,  6 );
234     P2( C, D, E, A, B,  8, 13,  6,  6 );
235     P2( B, C, D, E, A,  1, 15,  9, 14 );
236     P2( A, B, C, D, E,  2, 14, 11, 12 );
237     P2( E, A, B, C, D,  7,  8,  8, 13 );
238     P2( D, E, A, B, C,  0, 13, 12,  5 );
239     P2( C, D, E, A, B,  6,  6,  2, 14 );
240     P2( B, C, D, E, A, 13,  5, 10, 13 );
241     P2( A, B, C, D, E, 11, 12,  0, 13 );
242     P2( E, A, B, C, D,  5,  7,  4,  7 );
243     P2( D, E, A, B, C, 12,  5, 13,  5 );
244 #undef F
245 #undef K
246 #undef Fp
247 #undef Kp
248
249 #define F   F4
250 #define K   0x8F1BBCDC
251 #define Fp  F2
252 #define Kp  0x7A6D76E9
253     P2( C, D, E, A, B,  1, 11,  8, 15 );
254     P2( B, C, D, E, A,  9, 12,  6,  5 );
255     P2( A, B, C, D, E, 11, 14,  4,  8 );
256     P2( E, A, B, C, D, 10, 15,  1, 11 );
257     P2( D, E, A, B, C,  0, 14,  3, 14 );
258     P2( C, D, E, A, B,  8, 15, 11, 14 );
259     P2( B, C, D, E, A, 12,  9, 15,  6 );
260     P2( A, B, C, D, E,  4,  8,  0, 14 );
261     P2( E, A, B, C, D, 13,  9,  5,  6 );
262     P2( D, E, A, B, C,  3, 14, 12,  9 );
263     P2( C, D, E, A, B,  7,  5,  2, 12 );
264     P2( B, C, D, E, A, 15,  6, 13,  9 );
265     P2( A, B, C, D, E, 14,  8,  9, 12 );
266     P2( E, A, B, C, D,  5,  6,  7,  5 );
267     P2( D, E, A, B, C,  6,  5, 10, 15 );
268     P2( C, D, E, A, B,  2, 12, 14,  8 );
269 #undef F
270 #undef K
271 #undef Fp
272 #undef Kp
273
274 #define F   F5
275 #define K   0xA953FD4E
276 #define Fp  F1
277 #define Kp  0x00000000
278     P2( B, C, D, E, A,  4,  9, 12,  8 );
279     P2( A, B, C, D, E,  0, 15, 15,  5 );
280     P2( E, A, B, C, D,  5,  5, 10, 12 );
281     P2( D, E, A, B, C,  9, 11,  4,  9 );
282     P2( C, D, E, A, B,  7,  6,  1, 12 );
283     P2( B, C, D, E, A, 12,  8,  5,  5 );
284     P2( A, B, C, D, E,  2, 13,  8, 14 );
285     P2( E, A, B, C, D, 10, 12,  7,  6 );
286     P2( D, E, A, B, C, 14,  5,  6,  8 );
287     P2( C, D, E, A, B,  1, 12,  2, 13 );
288     P2( B, C, D, E, A,  3, 13, 13,  6 );
289     P2( A, B, C, D, E,  8, 14, 14,  5 );
290     P2( E, A, B, C, D, 11, 11,  0, 15 );
291     P2( D, E, A, B, C,  6,  8,  3, 13 );
292     P2( C, D, E, A, B, 15,  5,  9, 11 );
293     P2( B, C, D, E, A, 13,  6, 11, 11 );
294 #undef F
295 #undef K
296 #undef Fp
297 #undef Kp
298
299     C             = ctx->state[1] + C + Dp;
300     ctx->state[1] = ctx->state[2] + D + Ep;
301     ctx->state[2] = ctx->state[3] + E + Ap;
302     ctx->state[3] = ctx->state[4] + A + Bp;
303     ctx->state[4] = ctx->state[0] + B + Cp;
304     ctx->state[0] = C;
305
306     return( 0 );
307 }
308
309 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
310 void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
311                                 const unsigned char data[64] )
312 {
313     mbedtls_internal_ripemd160_process( ctx, data );
314 }
315 #endif
316 #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
317
318 /*
319  * RIPEMD-160 process buffer
320  */
321 int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
322                                   const unsigned char *input,
323                                   size_t ilen )
324 {
325     int ret;
326     size_t fill;
327     uint32_t left;
328
329     if( ilen == 0 )
330         return( 0 );
331
332     left = ctx->total[0] & 0x3F;
333     fill = 64 - left;
334
335     ctx->total[0] += (uint32_t) ilen;
336     ctx->total[0] &= 0xFFFFFFFF;
337
338     if( ctx->total[0] < (uint32_t) ilen )
339         ctx->total[1]++;
340
341     if( left && ilen >= fill )
342     {
343         memcpy( (void *) (ctx->buffer + left), input, fill );
344
345         if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
346             return( ret );
347
348         input += fill;
349         ilen  -= fill;
350         left = 0;
351     }
352
353     while( ilen >= 64 )
354     {
355         if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
356             return( ret );
357
358         input += 64;
359         ilen  -= 64;
360     }
361
362     if( ilen > 0 )
363     {
364         memcpy( (void *) (ctx->buffer + left), input, ilen );
365     }
366
367     return( 0 );
368 }
369
370 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
371 void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
372                                const unsigned char *input,
373                                size_t ilen )
374 {
375     mbedtls_ripemd160_update_ret( ctx, input, ilen );
376 }
377 #endif
378
379 static const unsigned char ripemd160_padding[64] =
380 {
381  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
382     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
383     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
384     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
385 };
386
387 /*
388  * RIPEMD-160 final digest
389  */
390 int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
391                                   unsigned char output[20] )
392 {
393     int ret;
394     uint32_t last, padn;
395     uint32_t high, low;
396     unsigned char msglen[8];
397
398     high = ( ctx->total[0] >> 29 )
399          | ( ctx->total[1] <<  3 );
400     low  = ( ctx->total[0] <<  3 );
401
402     PUT_UINT32_LE( low,  msglen, 0 );
403     PUT_UINT32_LE( high, msglen, 4 );
404
405     last = ctx->total[0] & 0x3F;
406     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
407
408     ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
409     if( ret != 0 )
410         return( ret );
411
412     ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
413     if( ret != 0 )
414         return( ret );
415
416     PUT_UINT32_LE( ctx->state[0], output,  0 );
417     PUT_UINT32_LE( ctx->state[1], output,  4 );
418     PUT_UINT32_LE( ctx->state[2], output,  8 );
419     PUT_UINT32_LE( ctx->state[3], output, 12 );
420     PUT_UINT32_LE( ctx->state[4], output, 16 );
421
422     return( 0 );
423 }
424
425 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
426 void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
427                                unsigned char output[20] )
428 {
429     mbedtls_ripemd160_finish_ret( ctx, output );
430 }
431 #endif
432
433 #endif /* ! MBEDTLS_RIPEMD160_ALT */
434
435 /*
436  * output = RIPEMD-160( input buffer )
437  */
438 int mbedtls_ripemd160_ret( const unsigned char *input,
439                            size_t ilen,
440                            unsigned char output[20] )
441 {
442     int ret;
443     mbedtls_ripemd160_context ctx;
444
445     mbedtls_ripemd160_init( &ctx );
446
447     if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
448         goto exit;
449
450     if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
451         goto exit;
452
453     if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
454         goto exit;
455
456 exit:
457     mbedtls_ripemd160_free( &ctx );
458
459     return( ret );
460 }
461
462 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
463 void mbedtls_ripemd160( const unsigned char *input,
464                         size_t ilen,
465                         unsigned char output[20] )
466 {
467     mbedtls_ripemd160_ret( input, ilen, output );
468 }
469 #endif
470
471 #if defined(MBEDTLS_SELF_TEST)
472 /*
473  * Test vectors from the RIPEMD-160 paper and
474  * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
475  */
476 #define TESTS   8
477 static const unsigned char ripemd160_test_str[TESTS][81] =
478 {
479     { "" },
480     { "a" },
481     { "abc" },
482     { "message digest" },
483     { "abcdefghijklmnopqrstuvwxyz" },
484     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
485     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
486     { "12345678901234567890123456789012345678901234567890123456789012"
487       "345678901234567890" },
488 };
489
490 static const size_t ripemd160_test_strlen[TESTS] =
491 {
492     0, 1, 3, 14, 26, 56, 62, 80
493 };
494
495 static const unsigned char ripemd160_test_md[TESTS][20] =
496 {
497     { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
498       0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
499     { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
500       0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
501     { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
502       0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
503     { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
504       0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
505     { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
506       0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
507     { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
508       0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
509     { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
510       0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
511     { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
512       0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
513 };
514
515 /*
516  * Checkup routine
517  */
518 int mbedtls_ripemd160_self_test( int verbose )
519 {
520     int i, ret = 0;
521     unsigned char output[20];
522
523     memset( output, 0, sizeof output );
524
525     for( i = 0; i < TESTS; i++ )
526     {
527         if( verbose != 0 )
528             mbedtls_printf( "  RIPEMD-160 test #%d: ", i + 1 );
529
530         ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
531                                      ripemd160_test_strlen[i], output );
532         if( ret != 0 )
533             goto fail;
534
535         if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
536         {
537             ret = 1;
538             goto fail;
539         }
540
541         if( verbose != 0 )
542             mbedtls_printf( "passed\n" );
543     }
544
545     if( verbose != 0 )
546         mbedtls_printf( "\n" );
547
548     return( 0 );
549
550 fail:
551     if( verbose != 0 )
552         mbedtls_printf( "failed\n" );
553
554     return( ret );
555 }
556
557 #endif /* MBEDTLS_SELF_TEST */
558
559 #endif /* MBEDTLS_RIPEMD160_C */