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"
51 #define mbedtls_printf printf
52 #define mbedtls_calloc calloc
53 #define mbedtls_free free
54 #endif /* MBEDTLS_PLATFORM_C */
55 #endif /* MBEDTLS_SELF_TEST */
57 #if !defined(MBEDTLS_SHA512_ALT)
59 /* Implementation that should never be optimized out by the compiler */
60 static void mbedtls_zeroize( void *v, size_t n ) {
61 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
65 * 64-bit integer manipulation macros (big endian)
68 #define GET_UINT64_BE(n,b,i) \
70 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
71 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
72 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
73 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
74 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
75 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
76 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
77 | ( (uint64_t) (b)[(i) + 7] ); \
79 #endif /* GET_UINT64_BE */
82 #define PUT_UINT64_BE(n,b,i) \
84 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
85 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
86 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
87 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
88 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
89 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
90 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
91 (b)[(i) + 7] = (unsigned char) ( (n) ); \
93 #endif /* PUT_UINT64_BE */
95 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
97 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
100 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
105 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
108 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
109 const mbedtls_sha512_context *src )
115 * SHA-512 context setup
117 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
125 ctx->state[0] = UL64(0x6A09E667F3BCC908);
126 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
127 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
128 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
129 ctx->state[4] = UL64(0x510E527FADE682D1);
130 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
131 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
132 ctx->state[7] = UL64(0x5BE0CD19137E2179);
137 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
138 ctx->state[1] = UL64(0x629A292A367CD507);
139 ctx->state[2] = UL64(0x9159015A3070DD17);
140 ctx->state[3] = UL64(0x152FECD8F70E5939);
141 ctx->state[4] = UL64(0x67332667FFC00B31);
142 ctx->state[5] = UL64(0x8EB44A8768581511);
143 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
144 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
152 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
155 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 void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
280 const unsigned char data[128] )
282 mbedtls_internal_sha512_process( ctx, data );
284 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
287 * SHA-512 process buffer
289 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
290 const unsigned char *input,
300 left = (unsigned int) (ctx->total[0] & 0x7F);
303 ctx->total[0] += (uint64_t) ilen;
305 if( ctx->total[0] < (uint64_t) ilen )
308 if( left && ilen >= fill )
310 memcpy( (void *) (ctx->buffer + left), input, fill );
312 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
322 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
330 memcpy( (void *) (ctx->buffer + left), input, ilen );
335 void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
336 const unsigned char *input,
339 mbedtls_sha512_update_ret( ctx, input, ilen );
343 * SHA-512 final digest
345 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
346 unsigned char output[64] )
353 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
355 used = ctx->total[0] & 0x7F;
357 ctx->buffer[used++] = 0x80;
361 /* Enough room for padding + length in current block */
362 memset( ctx->buffer + used, 0, 112 - used );
366 /* We'll need an extra block */
367 memset( ctx->buffer + used, 0, 128 - used );
369 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
372 memset( ctx->buffer, 0, 112 );
378 high = ( ctx->total[0] >> 61 )
379 | ( ctx->total[1] << 3 );
380 low = ( ctx->total[0] << 3 );
382 PUT_UINT64_BE( high, ctx->buffer, 112 );
383 PUT_UINT64_BE( low, ctx->buffer, 120 );
385 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
391 PUT_UINT64_BE( ctx->state[0], output, 0 );
392 PUT_UINT64_BE( ctx->state[1], output, 8 );
393 PUT_UINT64_BE( ctx->state[2], output, 16 );
394 PUT_UINT64_BE( ctx->state[3], output, 24 );
395 PUT_UINT64_BE( ctx->state[4], output, 32 );
396 PUT_UINT64_BE( ctx->state[5], output, 40 );
398 if( ctx->is384 == 0 )
400 PUT_UINT64_BE( ctx->state[6], output, 48 );
401 PUT_UINT64_BE( ctx->state[7], output, 56 );
407 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
408 unsigned char output[64] )
410 mbedtls_sha512_finish_ret( ctx, output );
413 #endif /* !MBEDTLS_SHA512_ALT */
416 * output = SHA-512( input buffer )
418 int mbedtls_sha512_ret( const unsigned char *input,
420 unsigned char output[64],
424 mbedtls_sha512_context ctx;
426 mbedtls_sha512_init( &ctx );
428 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
431 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
434 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
438 mbedtls_sha512_free( &ctx );
443 void mbedtls_sha512( const unsigned char *input,
445 unsigned char output[64],
448 mbedtls_sha512_ret( input, ilen, output, is384 );
451 #if defined(MBEDTLS_SELF_TEST)
454 * FIPS-180-2 test vectors
456 static const unsigned char sha512_test_buf[3][113] =
459 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
460 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
464 static const size_t sha512_test_buflen[3] =
469 static const unsigned char sha512_test_sum[6][64] =
472 * SHA-384 test vectors
474 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
475 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
476 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
477 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
478 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
479 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
480 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
481 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
482 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
483 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
484 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
485 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
486 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
487 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
488 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
489 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
490 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
491 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
494 * SHA-512 test vectors
496 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
497 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
498 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
499 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
500 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
501 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
502 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
503 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
504 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
505 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
506 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
507 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
508 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
509 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
510 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
511 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
512 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
513 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
514 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
515 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
516 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
517 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
518 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
519 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
525 int mbedtls_sha512_self_test( int verbose )
527 int i, j, k, buflen, ret = 0;
529 unsigned char sha512sum[64];
530 mbedtls_sha512_context ctx;
532 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
536 mbedtls_printf( "Buffer allocation failed\n" );
541 mbedtls_sha512_init( &ctx );
543 for( i = 0; i < 6; i++ )
549 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
551 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
556 memset( buf, 'a', buflen = 1000 );
558 for( j = 0; j < 1000; j++ )
560 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
567 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
568 sha512_test_buflen[j] );
573 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
576 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
583 mbedtls_printf( "passed\n" );
587 mbedtls_printf( "\n" );
593 mbedtls_printf( "failed\n" );
596 mbedtls_sha512_free( &ctx );
602 #endif /* MBEDTLS_SELF_TEST */
604 #endif /* MBEDTLS_SHA512_C */