2 * FIPS-180-2 compliant SHA-384/512 implementation
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * This file is part of mbed TLS (https://tls.mbed.org)
22 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
24 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
27 #if !defined(MBEDTLS_CONFIG_FILE)
28 #include "mbedtls/config.h"
30 #include MBEDTLS_CONFIG_FILE
33 #if defined(MBEDTLS_SHA512_C)
35 #include "mbedtls/sha512.h"
37 #if defined(_MSC_VER) || defined(__WATCOMC__)
38 #define UL64(x) x##ui64
40 #define UL64(x) x##ULL
45 #if defined(MBEDTLS_SELF_TEST)
46 #if defined(MBEDTLS_PLATFORM_C)
47 #include "mbedtls/platform.h"
50 #define mbedtls_printf printf
51 #endif /* MBEDTLS_PLATFORM_C */
52 #endif /* MBEDTLS_SELF_TEST */
54 #if !defined(MBEDTLS_SHA512_ALT)
56 /* Implementation that should never be optimized out by the compiler */
57 static void mbedtls_zeroize( void *v
, size_t n
) {
58 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
62 * 64-bit integer manipulation macros (big endian)
65 #define GET_UINT64_BE(n,b,i) \
67 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
68 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
69 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
70 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
71 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
72 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
73 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
74 | ( (uint64_t) (b)[(i) + 7] ); \
76 #endif /* GET_UINT64_BE */
79 #define PUT_UINT64_BE(n,b,i) \
81 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
82 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
83 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
84 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
85 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
86 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
87 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
88 (b)[(i) + 7] = (unsigned char) ( (n) ); \
90 #endif /* PUT_UINT64_BE */
95 static const uint64_t K
[80] =
97 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
98 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
99 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
100 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
101 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
102 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
103 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
104 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
105 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
106 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
107 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
108 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
109 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
110 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
111 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
112 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
113 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
114 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
115 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
116 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
117 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
118 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
119 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
120 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
121 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
122 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
123 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
124 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
125 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
126 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
127 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
128 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
129 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
130 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
131 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
132 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
133 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
134 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
135 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
136 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
139 void mbedtls_sha512_init( mbedtls_sha512_context
*ctx
)
141 memset( ctx
, 0, sizeof( mbedtls_sha512_context
) );
144 void mbedtls_sha512_free( mbedtls_sha512_context
*ctx
)
149 mbedtls_zeroize( ctx
, sizeof( mbedtls_sha512_context
) );
152 void mbedtls_sha512_clone( mbedtls_sha512_context
*dst
,
153 const mbedtls_sha512_context
*src
)
159 * SHA-512 context setup
161 void mbedtls_sha512_starts( mbedtls_sha512_context
*ctx
, int is384
)
169 ctx
->state
[0] = UL64(0x6A09E667F3BCC908);
170 ctx
->state
[1] = UL64(0xBB67AE8584CAA73B);
171 ctx
->state
[2] = UL64(0x3C6EF372FE94F82B);
172 ctx
->state
[3] = UL64(0xA54FF53A5F1D36F1);
173 ctx
->state
[4] = UL64(0x510E527FADE682D1);
174 ctx
->state
[5] = UL64(0x9B05688C2B3E6C1F);
175 ctx
->state
[6] = UL64(0x1F83D9ABFB41BD6B);
176 ctx
->state
[7] = UL64(0x5BE0CD19137E2179);
181 ctx
->state
[0] = UL64(0xCBBB9D5DC1059ED8);
182 ctx
->state
[1] = UL64(0x629A292A367CD507);
183 ctx
->state
[2] = UL64(0x9159015A3070DD17);
184 ctx
->state
[3] = UL64(0x152FECD8F70E5939);
185 ctx
->state
[4] = UL64(0x67332667FFC00B31);
186 ctx
->state
[5] = UL64(0x8EB44A8768581511);
187 ctx
->state
[6] = UL64(0xDB0C2E0D64F98FA7);
188 ctx
->state
[7] = UL64(0x47B5481DBEFA4FA4);
194 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
195 void mbedtls_sha512_process( mbedtls_sha512_context
*ctx
, const unsigned char data
[128] )
198 uint64_t temp1
, temp2
, W
[80];
199 uint64_t A
, B
, C
, D
, E
, F
, G
, H
;
201 #define SHR(x,n) (x >> n)
202 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
204 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
205 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
207 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
208 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
210 #define F0(x,y,z) ((x & y) | (z & (x | y)))
211 #define F1(x,y,z) (z ^ (x & (y ^ z)))
213 #define P(a,b,c,d,e,f,g,h,x,K) \
215 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
216 temp2 = S2(a) + F0(a,b,c); \
217 d += temp1; h = temp1 + temp2; \
220 for( i
= 0; i
< 16; i
++ )
222 GET_UINT64_BE( W
[i
], data
, i
<< 3 );
227 W
[i
] = S1(W
[i
- 2]) + W
[i
- 7] +
228 S0(W
[i
- 15]) + W
[i
- 16];
243 P( A
, B
, C
, D
, E
, F
, G
, H
, W
[i
], K
[i
] ); i
++;
244 P( H
, A
, B
, C
, D
, E
, F
, G
, W
[i
], K
[i
] ); i
++;
245 P( G
, H
, A
, B
, C
, D
, E
, F
, W
[i
], K
[i
] ); i
++;
246 P( F
, G
, H
, A
, B
, C
, D
, E
, W
[i
], K
[i
] ); i
++;
247 P( E
, F
, G
, H
, A
, B
, C
, D
, W
[i
], K
[i
] ); i
++;
248 P( D
, E
, F
, G
, H
, A
, B
, C
, W
[i
], K
[i
] ); i
++;
249 P( C
, D
, E
, F
, G
, H
, A
, B
, W
[i
], K
[i
] ); i
++;
250 P( B
, C
, D
, E
, F
, G
, H
, A
, W
[i
], K
[i
] ); i
++;
263 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
266 * SHA-512 process buffer
268 void mbedtls_sha512_update( mbedtls_sha512_context
*ctx
, const unsigned char *input
,
277 left
= (unsigned int) (ctx
->total
[0] & 0x7F);
280 ctx
->total
[0] += (uint64_t) ilen
;
282 if( ctx
->total
[0] < (uint64_t) ilen
)
285 if( left
&& ilen
>= fill
)
287 memcpy( (void *) (ctx
->buffer
+ left
), input
, fill
);
288 mbedtls_sha512_process( ctx
, ctx
->buffer
);
296 mbedtls_sha512_process( ctx
, input
);
302 memcpy( (void *) (ctx
->buffer
+ left
), input
, ilen
);
305 static const unsigned char sha512_padding
[128] =
307 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
318 * SHA-512 final digest
320 void mbedtls_sha512_finish( mbedtls_sha512_context
*ctx
, unsigned char output
[64] )
324 unsigned char msglen
[16];
326 high
= ( ctx
->total
[0] >> 61 )
327 | ( ctx
->total
[1] << 3 );
328 low
= ( ctx
->total
[0] << 3 );
330 PUT_UINT64_BE( high
, msglen
, 0 );
331 PUT_UINT64_BE( low
, msglen
, 8 );
333 last
= (size_t)( ctx
->total
[0] & 0x7F );
334 padn
= ( last
< 112 ) ? ( 112 - last
) : ( 240 - last
);
336 mbedtls_sha512_update( ctx
, sha512_padding
, padn
);
337 mbedtls_sha512_update( ctx
, msglen
, 16 );
339 PUT_UINT64_BE( ctx
->state
[0], output
, 0 );
340 PUT_UINT64_BE( ctx
->state
[1], output
, 8 );
341 PUT_UINT64_BE( ctx
->state
[2], output
, 16 );
342 PUT_UINT64_BE( ctx
->state
[3], output
, 24 );
343 PUT_UINT64_BE( ctx
->state
[4], output
, 32 );
344 PUT_UINT64_BE( ctx
->state
[5], output
, 40 );
346 if( ctx
->is384
== 0 )
348 PUT_UINT64_BE( ctx
->state
[6], output
, 48 );
349 PUT_UINT64_BE( ctx
->state
[7], output
, 56 );
353 #endif /* !MBEDTLS_SHA512_ALT */
356 * output = SHA-512( input buffer )
358 void mbedtls_sha512( const unsigned char *input
, size_t ilen
,
359 unsigned char output
[64], int is384
)
361 mbedtls_sha512_context ctx
;
363 mbedtls_sha512_init( &ctx
);
364 mbedtls_sha512_starts( &ctx
, is384
);
365 mbedtls_sha512_update( &ctx
, input
, ilen
);
366 mbedtls_sha512_finish( &ctx
, output
);
367 mbedtls_sha512_free( &ctx
);
370 #if defined(MBEDTLS_SELF_TEST)
373 * FIPS-180-2 test vectors
375 static const unsigned char sha512_test_buf
[3][113] =
378 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
379 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
383 static const int sha512_test_buflen
[3] =
388 static const unsigned char sha512_test_sum
[6][64] =
391 * SHA-384 test vectors
393 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
394 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
395 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
396 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
397 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
398 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
399 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
400 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
401 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
402 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
403 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
404 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
405 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
406 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
407 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
408 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
409 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
410 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
413 * SHA-512 test vectors
415 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
416 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
417 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
418 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
419 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
420 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
421 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
422 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
423 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
424 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
425 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
426 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
427 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
428 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
429 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
430 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
431 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
432 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
433 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
434 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
435 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
436 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
437 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
438 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
444 int mbedtls_sha512_self_test( int verbose
)
446 int i
, j
, k
, buflen
, ret
= 0;
447 unsigned char buf
[1024];
448 unsigned char sha512sum
[64];
449 mbedtls_sha512_context ctx
;
451 mbedtls_sha512_init( &ctx
);
453 for( i
= 0; i
< 6; i
++ )
459 mbedtls_printf( " SHA-%d test #%d: ", 512 - k
* 128, j
+ 1 );
461 mbedtls_sha512_starts( &ctx
, k
);
465 memset( buf
, 'a', buflen
= 1000 );
467 for( j
= 0; j
< 1000; j
++ )
468 mbedtls_sha512_update( &ctx
, buf
, buflen
);
471 mbedtls_sha512_update( &ctx
, sha512_test_buf
[j
],
472 sha512_test_buflen
[j
] );
474 mbedtls_sha512_finish( &ctx
, sha512sum
);
476 if( memcmp( sha512sum
, sha512_test_sum
[i
], 64 - k
* 16 ) != 0 )
479 mbedtls_printf( "failed\n" );
486 mbedtls_printf( "passed\n" );
490 mbedtls_printf( "\n" );
493 mbedtls_sha512_free( &ctx
);
498 #endif /* MBEDTLS_SELF_TEST */
500 #endif /* MBEDTLS_SHA512_C */