2 * FIPS-180-2 compliant SHA-384/512 implementation
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
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.
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.
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.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
26 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
29 #if !defined(MBEDTLS_CONFIG_FILE)
30 #include "mbedtls/config.h"
32 #include MBEDTLS_CONFIG_FILE
35 #if defined(MBEDTLS_SHA512_C)
37 #include "mbedtls/sha512.h"
38 #include "mbedtls/platform_util.h"
40 #if defined(_MSC_VER) || defined(__WATCOMC__)
41 #define UL64(x) x##ui64
43 #define UL64(x) x##ULL
48 #if defined(MBEDTLS_SELF_TEST)
49 #if defined(MBEDTLS_PLATFORM_C)
50 #include "mbedtls/platform.h"
54 #define mbedtls_printf printf
55 #define mbedtls_calloc calloc
56 #define mbedtls_free free
57 #endif /* MBEDTLS_PLATFORM_C */
58 #endif /* MBEDTLS_SELF_TEST */
60 #if !defined(MBEDTLS_SHA512_ALT)
63 * 64-bit integer manipulation macros (big endian)
66 #define GET_UINT64_BE(n,b,i) \
68 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
69 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
70 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
71 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
72 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
73 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
74 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
75 | ( (uint64_t) (b)[(i) + 7] ); \
77 #endif /* GET_UINT64_BE */
80 #define PUT_UINT64_BE(n,b,i) \
82 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
83 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
84 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
85 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
86 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
87 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
88 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
89 (b)[(i) + 7] = (unsigned char) ( (n) ); \
91 #endif /* PUT_UINT64_BE */
93 void mbedtls_sha512_init( mbedtls_sha512_context
*ctx
)
95 memset( ctx
, 0, sizeof( mbedtls_sha512_context
) );
98 void mbedtls_sha512_free( mbedtls_sha512_context
*ctx
)
103 mbedtls_platform_zeroize( ctx
, sizeof( mbedtls_sha512_context
) );
106 void mbedtls_sha512_clone( mbedtls_sha512_context
*dst
,
107 const mbedtls_sha512_context
*src
)
113 * SHA-512 context setup
115 int mbedtls_sha512_starts_ret( mbedtls_sha512_context
*ctx
, int is384
)
123 ctx
->state
[0] = UL64(0x6A09E667F3BCC908);
124 ctx
->state
[1] = UL64(0xBB67AE8584CAA73B);
125 ctx
->state
[2] = UL64(0x3C6EF372FE94F82B);
126 ctx
->state
[3] = UL64(0xA54FF53A5F1D36F1);
127 ctx
->state
[4] = UL64(0x510E527FADE682D1);
128 ctx
->state
[5] = UL64(0x9B05688C2B3E6C1F);
129 ctx
->state
[6] = UL64(0x1F83D9ABFB41BD6B);
130 ctx
->state
[7] = UL64(0x5BE0CD19137E2179);
135 ctx
->state
[0] = UL64(0xCBBB9D5DC1059ED8);
136 ctx
->state
[1] = UL64(0x629A292A367CD507);
137 ctx
->state
[2] = UL64(0x9159015A3070DD17);
138 ctx
->state
[3] = UL64(0x152FECD8F70E5939);
139 ctx
->state
[4] = UL64(0x67332667FFC00B31);
140 ctx
->state
[5] = UL64(0x8EB44A8768581511);
141 ctx
->state
[6] = UL64(0xDB0C2E0D64F98FA7);
142 ctx
->state
[7] = UL64(0x47B5481DBEFA4FA4);
150 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
151 void mbedtls_sha512_starts( mbedtls_sha512_context
*ctx
,
154 mbedtls_sha512_starts_ret( ctx
, is384
);
158 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
163 static const uint64_t K
[80] =
165 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
166 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
167 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
168 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
169 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
170 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
171 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
172 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
173 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
174 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
175 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
176 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
177 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
178 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
179 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
180 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
181 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
182 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
183 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
184 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
185 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
186 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
187 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
188 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
189 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
190 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
191 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
192 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
193 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
194 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
195 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
196 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
197 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
198 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
199 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
200 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
201 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
202 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
203 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
204 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
207 int mbedtls_internal_sha512_process( mbedtls_sha512_context
*ctx
,
208 const unsigned char data
[128] )
211 uint64_t temp1
, temp2
, W
[80];
212 uint64_t A
, B
, C
, D
, E
, F
, G
, H
;
214 #define SHR(x,n) (x >> n)
215 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
217 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
218 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
220 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
221 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
223 #define F0(x,y,z) ((x & y) | (z & (x | y)))
224 #define F1(x,y,z) (z ^ (x & (y ^ z)))
226 #define P(a,b,c,d,e,f,g,h,x,K) \
228 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
229 temp2 = S2(a) + F0(a,b,c); \
230 d += temp1; h = temp1 + temp2; \
233 for( i
= 0; i
< 16; i
++ )
235 GET_UINT64_BE( W
[i
], data
, i
<< 3 );
240 W
[i
] = S1(W
[i
- 2]) + W
[i
- 7] +
241 S0(W
[i
- 15]) + W
[i
- 16];
256 P( A
, B
, C
, D
, E
, F
, G
, H
, W
[i
], K
[i
] ); i
++;
257 P( H
, A
, B
, C
, D
, E
, F
, G
, W
[i
], K
[i
] ); i
++;
258 P( G
, H
, A
, B
, C
, D
, E
, F
, W
[i
], K
[i
] ); i
++;
259 P( F
, G
, H
, A
, B
, C
, D
, E
, W
[i
], K
[i
] ); i
++;
260 P( E
, F
, G
, H
, A
, B
, C
, D
, W
[i
], K
[i
] ); i
++;
261 P( D
, E
, F
, G
, H
, A
, B
, C
, W
[i
], K
[i
] ); i
++;
262 P( C
, D
, E
, F
, G
, H
, A
, B
, W
[i
], K
[i
] ); i
++;
263 P( B
, C
, D
, E
, F
, G
, H
, A
, W
[i
], K
[i
] ); i
++;
279 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
280 void mbedtls_sha512_process( mbedtls_sha512_context
*ctx
,
281 const unsigned char data
[128] )
283 mbedtls_internal_sha512_process( ctx
, data
);
286 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
289 * SHA-512 process buffer
291 int mbedtls_sha512_update_ret( mbedtls_sha512_context
*ctx
,
292 const unsigned char *input
,
302 left
= (unsigned int) (ctx
->total
[0] & 0x7F);
305 ctx
->total
[0] += (uint64_t) ilen
;
307 if( ctx
->total
[0] < (uint64_t) ilen
)
310 if( left
&& ilen
>= fill
)
312 memcpy( (void *) (ctx
->buffer
+ left
), input
, fill
);
314 if( ( ret
= mbedtls_internal_sha512_process( ctx
, ctx
->buffer
) ) != 0 )
324 if( ( ret
= mbedtls_internal_sha512_process( ctx
, input
) ) != 0 )
332 memcpy( (void *) (ctx
->buffer
+ left
), input
, ilen
);
337 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
338 void mbedtls_sha512_update( mbedtls_sha512_context
*ctx
,
339 const unsigned char *input
,
342 mbedtls_sha512_update_ret( ctx
, input
, ilen
);
347 * SHA-512 final digest
349 int mbedtls_sha512_finish_ret( mbedtls_sha512_context
*ctx
,
350 unsigned char output
[64] )
357 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
359 used
= ctx
->total
[0] & 0x7F;
361 ctx
->buffer
[used
++] = 0x80;
365 /* Enough room for padding + length in current block */
366 memset( ctx
->buffer
+ used
, 0, 112 - used
);
370 /* We'll need an extra block */
371 memset( ctx
->buffer
+ used
, 0, 128 - used
);
373 if( ( ret
= mbedtls_internal_sha512_process( ctx
, ctx
->buffer
) ) != 0 )
376 memset( ctx
->buffer
, 0, 112 );
382 high
= ( ctx
->total
[0] >> 61 )
383 | ( ctx
->total
[1] << 3 );
384 low
= ( ctx
->total
[0] << 3 );
386 PUT_UINT64_BE( high
, ctx
->buffer
, 112 );
387 PUT_UINT64_BE( low
, ctx
->buffer
, 120 );
389 if( ( ret
= mbedtls_internal_sha512_process( ctx
, ctx
->buffer
) ) != 0 )
395 PUT_UINT64_BE( ctx
->state
[0], output
, 0 );
396 PUT_UINT64_BE( ctx
->state
[1], output
, 8 );
397 PUT_UINT64_BE( ctx
->state
[2], output
, 16 );
398 PUT_UINT64_BE( ctx
->state
[3], output
, 24 );
399 PUT_UINT64_BE( ctx
->state
[4], output
, 32 );
400 PUT_UINT64_BE( ctx
->state
[5], output
, 40 );
402 if( ctx
->is384
== 0 )
404 PUT_UINT64_BE( ctx
->state
[6], output
, 48 );
405 PUT_UINT64_BE( ctx
->state
[7], output
, 56 );
411 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
412 void mbedtls_sha512_finish( mbedtls_sha512_context
*ctx
,
413 unsigned char output
[64] )
415 mbedtls_sha512_finish_ret( ctx
, output
);
419 #endif /* !MBEDTLS_SHA512_ALT */
422 * output = SHA-512( input buffer )
424 int mbedtls_sha512_ret( const unsigned char *input
,
426 unsigned char output
[64],
430 mbedtls_sha512_context ctx
;
432 mbedtls_sha512_init( &ctx
);
434 if( ( ret
= mbedtls_sha512_starts_ret( &ctx
, is384
) ) != 0 )
437 if( ( ret
= mbedtls_sha512_update_ret( &ctx
, input
, ilen
) ) != 0 )
440 if( ( ret
= mbedtls_sha512_finish_ret( &ctx
, output
) ) != 0 )
444 mbedtls_sha512_free( &ctx
);
449 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
450 void mbedtls_sha512( const unsigned char *input
,
452 unsigned char output
[64],
455 mbedtls_sha512_ret( input
, ilen
, output
, is384
);
459 #if defined(MBEDTLS_SELF_TEST)
462 * FIPS-180-2 test vectors
464 static const unsigned char sha512_test_buf
[3][113] =
467 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
468 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
472 static const size_t sha512_test_buflen
[3] =
477 static const unsigned char sha512_test_sum
[6][64] =
480 * SHA-384 test vectors
482 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
483 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
484 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
485 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
486 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
487 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
488 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
489 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
490 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
491 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
492 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
493 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
494 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
495 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
496 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
497 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
498 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
499 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
502 * SHA-512 test vectors
504 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
505 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
506 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
507 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
508 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
509 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
510 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
511 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
512 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
513 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
514 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
515 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
516 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
517 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
518 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
519 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
520 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
521 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
522 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
523 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
524 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
525 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
526 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
527 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
533 int mbedtls_sha512_self_test( int verbose
)
535 int i
, j
, k
, buflen
, ret
= 0;
537 unsigned char sha512sum
[64];
538 mbedtls_sha512_context ctx
;
540 buf
= mbedtls_calloc( 1024, sizeof(unsigned char) );
544 mbedtls_printf( "Buffer allocation failed\n" );
549 mbedtls_sha512_init( &ctx
);
551 for( i
= 0; i
< 6; i
++ )
557 mbedtls_printf( " SHA-%d test #%d: ", 512 - k
* 128, j
+ 1 );
559 if( ( ret
= mbedtls_sha512_starts_ret( &ctx
, k
) ) != 0 )
564 memset( buf
, 'a', buflen
= 1000 );
566 for( j
= 0; j
< 1000; j
++ )
568 ret
= mbedtls_sha512_update_ret( &ctx
, buf
, buflen
);
575 ret
= mbedtls_sha512_update_ret( &ctx
, sha512_test_buf
[j
],
576 sha512_test_buflen
[j
] );
581 if( ( ret
= mbedtls_sha512_finish_ret( &ctx
, sha512sum
) ) != 0 )
584 if( memcmp( sha512sum
, sha512_test_sum
[i
], 64 - k
* 16 ) != 0 )
591 mbedtls_printf( "passed\n" );
595 mbedtls_printf( "\n" );
601 mbedtls_printf( "failed\n" );
604 mbedtls_sha512_free( &ctx
);
610 #endif /* MBEDTLS_SELF_TEST */
612 #endif /* MBEDTLS_SHA512_C */