mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sha512.c Source File

sha512.c

00001 /*
00002  *  FIPS-180-2 compliant SHA-384/512 implementation
00003  *
00004  *  Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
00005  *
00006  *  This file is part of mbed TLS (https://tls.mbed.org)
00007  *
00008  *  This program is free software; you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation; either version 2 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public License along
00019  *  with this program; if not, write to the Free Software Foundation, Inc.,
00020  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00021  */
00022 /*
00023  *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
00024  *
00025  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
00026  */
00027 
00028 #if !defined(POLARSSL_CONFIG_FILE)
00029 #include "polarssl/config.h"
00030 #else
00031 #include POLARSSL_CONFIG_FILE
00032 #endif
00033 
00034 #if defined(POLARSSL_SHA512_C)
00035 
00036 #include "polarssl/sha512.h"
00037 
00038 #if defined(_MSC_VER) || defined(__WATCOMC__)
00039   #define UL64(x) x##ui64
00040 #else
00041   #define UL64(x) x##ULL
00042 #endif
00043 
00044 #include <string.h>
00045 
00046 #if defined(POLARSSL_FS_IO)
00047 #include <stdio.h>
00048 #endif
00049 
00050 #if defined(POLARSSL_SELF_TEST)
00051 #if defined(POLARSSL_PLATFORM_C)
00052 #include "polarssl/platform.h"
00053 #else
00054 #include <stdio.h>
00055 #define polarssl_printf printf
00056 #endif /* POLARSSL_PLATFORM_C */
00057 #endif /* POLARSSL_SELF_TEST */
00058 
00059 /* Implementation that should never be optimized out by the compiler */
00060 static void polarssl_zeroize( void *v, size_t n ) {
00061     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00062 }
00063 
00064 #if !defined(POLARSSL_SHA512_ALT)
00065 
00066 /*
00067  * 64-bit integer manipulation macros (big endian)
00068  */
00069 #ifndef GET_UINT64_BE
00070 #define GET_UINT64_BE(n,b,i)                            \
00071 {                                                       \
00072     (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
00073         | ( (uint64_t) (b)[(i) + 1] << 48 )       \
00074         | ( (uint64_t) (b)[(i) + 2] << 40 )       \
00075         | ( (uint64_t) (b)[(i) + 3] << 32 )       \
00076         | ( (uint64_t) (b)[(i) + 4] << 24 )       \
00077         | ( (uint64_t) (b)[(i) + 5] << 16 )       \
00078         | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
00079         | ( (uint64_t) (b)[(i) + 7]       );      \
00080 }
00081 #endif /* GET_UINT64_BE */
00082 
00083 #ifndef PUT_UINT64_BE
00084 #define PUT_UINT64_BE(n,b,i)                            \
00085 {                                                       \
00086     (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
00087     (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
00088     (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
00089     (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
00090     (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
00091     (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
00092     (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
00093     (b)[(i) + 7] = (unsigned char) ( (n)       );       \
00094 }
00095 #endif /* PUT_UINT64_BE */
00096 
00097 /*
00098  * Round constants
00099  */
00100 static const uint64_t K[80] =
00101 {
00102     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
00103     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
00104     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
00105     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
00106     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
00107     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
00108     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
00109     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
00110     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
00111     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
00112     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
00113     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
00114     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
00115     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
00116     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
00117     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
00118     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
00119     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
00120     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
00121     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
00122     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
00123     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
00124     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
00125     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
00126     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
00127     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
00128     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
00129     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
00130     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
00131     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
00132     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
00133     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
00134     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
00135     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
00136     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
00137     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
00138     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
00139     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
00140     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
00141     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
00142 };
00143 
00144 void sha512_init( sha512_context *ctx )
00145 {
00146     memset( ctx, 0, sizeof( sha512_context ) );
00147 }
00148 
00149 void sha512_free( sha512_context *ctx )
00150 {
00151     if( ctx == NULL )
00152         return;
00153 
00154     polarssl_zeroize( ctx, sizeof( sha512_context ) );
00155 }
00156 
00157 /*
00158  * SHA-512 context setup
00159  */
00160 void sha512_starts( sha512_context *ctx, int is384 )
00161 {
00162     ctx->total [0] = 0;
00163     ctx->total [1] = 0;
00164 
00165     if( is384 == 0 )
00166     {
00167         /* SHA-512 */
00168         ctx->state [0] = UL64(0x6A09E667F3BCC908);
00169         ctx->state [1] = UL64(0xBB67AE8584CAA73B);
00170         ctx->state [2] = UL64(0x3C6EF372FE94F82B);
00171         ctx->state [3] = UL64(0xA54FF53A5F1D36F1);
00172         ctx->state [4] = UL64(0x510E527FADE682D1);
00173         ctx->state [5] = UL64(0x9B05688C2B3E6C1F);
00174         ctx->state [6] = UL64(0x1F83D9ABFB41BD6B);
00175         ctx->state [7] = UL64(0x5BE0CD19137E2179);
00176     }
00177     else
00178     {
00179         /* SHA-384 */
00180         ctx->state [0] = UL64(0xCBBB9D5DC1059ED8);
00181         ctx->state [1] = UL64(0x629A292A367CD507);
00182         ctx->state [2] = UL64(0x9159015A3070DD17);
00183         ctx->state [3] = UL64(0x152FECD8F70E5939);
00184         ctx->state [4] = UL64(0x67332667FFC00B31);
00185         ctx->state [5] = UL64(0x8EB44A8768581511);
00186         ctx->state [6] = UL64(0xDB0C2E0D64F98FA7);
00187         ctx->state [7] = UL64(0x47B5481DBEFA4FA4);
00188     }
00189 
00190     ctx->is384  = is384;
00191 }
00192 
00193 void sha512_process( sha512_context *ctx, const unsigned char data[128] )
00194 {
00195     int i;
00196     uint64_t temp1, temp2, W[80];
00197     uint64_t A, B, C, D, E, F, G, H;
00198 
00199 #define  SHR(x,n) (x >> n)
00200 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
00201 
00202 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
00203 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
00204 
00205 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
00206 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
00207 
00208 #define F0(x,y,z) ((x & y) | (z & (x | y)))
00209 #define F1(x,y,z) (z ^ (x & (y ^ z)))
00210 
00211 #define P(a,b,c,d,e,f,g,h,x,K)                  \
00212 {                                               \
00213     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
00214     temp2 = S2(a) + F0(a,b,c);                  \
00215     d += temp1; h = temp1 + temp2;              \
00216 }
00217 
00218     for( i = 0; i < 16; i++ )
00219     {
00220         GET_UINT64_BE( W[i], data, i << 3 );
00221     }
00222 
00223     for( ; i < 80; i++ )
00224     {
00225         W[i] = S1(W[i -  2]) + W[i -  7] +
00226                S0(W[i - 15]) + W[i - 16];
00227     }
00228 
00229     A = ctx->state [0];
00230     B = ctx->state [1];
00231     C = ctx->state [2];
00232     D = ctx->state [3];
00233     E = ctx->state [4];
00234     F = ctx->state [5];
00235     G = ctx->state [6];
00236     H = ctx->state [7];
00237     i = 0;
00238 
00239     do
00240     {
00241         P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
00242         P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
00243         P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
00244         P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
00245         P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
00246         P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
00247         P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
00248         P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
00249     }
00250     while( i < 80 );
00251 
00252     ctx->state [0] += A;
00253     ctx->state [1] += B;
00254     ctx->state [2] += C;
00255     ctx->state [3] += D;
00256     ctx->state [4] += E;
00257     ctx->state [5] += F;
00258     ctx->state [6] += G;
00259     ctx->state [7] += H;
00260 }
00261 
00262 /*
00263  * SHA-512 process buffer
00264  */
00265 void sha512_update( sha512_context *ctx, const unsigned char *input,
00266                     size_t ilen )
00267 {
00268     size_t fill;
00269     unsigned int left;
00270 
00271     if( ilen == 0 )
00272         return;
00273 
00274     left = (unsigned int) (ctx->total [0] & 0x7F);
00275     fill = 128 - left;
00276 
00277     ctx->total [0] += (uint64_t) ilen;
00278 
00279     if( ctx->total [0] < (uint64_t) ilen )
00280         ctx->total [1]++;
00281 
00282     if( left && ilen >= fill )
00283     {
00284         memcpy( (void *) (ctx->buffer  + left), input, fill );
00285         sha512_process( ctx, ctx->buffer  );
00286         input += fill;
00287         ilen  -= fill;
00288         left = 0;
00289     }
00290 
00291     while( ilen >= 128 )
00292     {
00293         sha512_process( ctx, input );
00294         input += 128;
00295         ilen  -= 128;
00296     }
00297 
00298     if( ilen > 0 )
00299         memcpy( (void *) (ctx->buffer  + left), input, ilen );
00300 }
00301 
00302 static const unsigned char sha512_padding[128] =
00303 {
00304  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00305     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00306     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00307     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00308     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00309     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00310     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00311     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00312 };
00313 
00314 /*
00315  * SHA-512 final digest
00316  */
00317 void sha512_finish( sha512_context *ctx, unsigned char output[64] )
00318 {
00319     size_t last, padn;
00320     uint64_t high, low;
00321     unsigned char msglen[16];
00322 
00323     high = ( ctx->total [0] >> 61 )
00324          | ( ctx->total [1] <<  3 );
00325     low  = ( ctx->total [0] <<  3 );
00326 
00327     PUT_UINT64_BE( high, msglen, 0 );
00328     PUT_UINT64_BE( low,  msglen, 8 );
00329 
00330     last = (size_t)( ctx->total [0] & 0x7F );
00331     padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
00332 
00333     sha512_update( ctx, sha512_padding, padn );
00334     sha512_update( ctx, msglen, 16 );
00335 
00336     PUT_UINT64_BE( ctx->state [0], output,  0 );
00337     PUT_UINT64_BE( ctx->state [1], output,  8 );
00338     PUT_UINT64_BE( ctx->state [2], output, 16 );
00339     PUT_UINT64_BE( ctx->state [3], output, 24 );
00340     PUT_UINT64_BE( ctx->state [4], output, 32 );
00341     PUT_UINT64_BE( ctx->state [5], output, 40 );
00342 
00343     if( ctx->is384  == 0 )
00344     {
00345         PUT_UINT64_BE( ctx->state [6], output, 48 );
00346         PUT_UINT64_BE( ctx->state [7], output, 56 );
00347     }
00348 }
00349 
00350 #endif /* !POLARSSL_SHA512_ALT */
00351 
00352 /*
00353  * output = SHA-512( input buffer )
00354  */
00355 void sha512( const unsigned char *input, size_t ilen,
00356              unsigned char output[64], int is384 )
00357 {
00358     sha512_context ctx;
00359 
00360     sha512_init( &ctx );
00361     sha512_starts( &ctx, is384 );
00362     sha512_update( &ctx, input, ilen );
00363     sha512_finish( &ctx, output );
00364     sha512_free( &ctx );
00365 }
00366 
00367 #if defined(POLARSSL_FS_IO)
00368 /*
00369  * output = SHA-512( file contents )
00370  */
00371 int sha512_file( const char *path, unsigned char output[64], int is384 )
00372 {
00373     FILE *f;
00374     size_t n;
00375     sha512_context ctx;
00376     unsigned char buf[1024];
00377 
00378     if( ( f = fopen( path, "rb" ) ) == NULL )
00379         return( POLARSSL_ERR_SHA512_FILE_IO_ERROR );
00380 
00381     sha512_init( &ctx );
00382     sha512_starts( &ctx, is384 );
00383 
00384     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00385         sha512_update( &ctx, buf, n );
00386 
00387     sha512_finish( &ctx, output );
00388     sha512_free( &ctx );
00389 
00390     if( ferror( f ) != 0 )
00391     {
00392         fclose( f );
00393         return( POLARSSL_ERR_SHA512_FILE_IO_ERROR );
00394     }
00395 
00396     fclose( f );
00397     return( 0 );
00398 }
00399 #endif /* POLARSSL_FS_IO */
00400 
00401 /*
00402  * SHA-512 HMAC context setup
00403  */
00404 void sha512_hmac_starts( sha512_context *ctx, const unsigned char *key,
00405                          size_t keylen, int is384 )
00406 {
00407     size_t i;
00408     unsigned char sum[64];
00409 
00410     if( keylen > 128 )
00411     {
00412         sha512( key, keylen, sum, is384 );
00413         keylen = ( is384 ) ? 48 : 64;
00414         key = sum;
00415     }
00416 
00417     memset( ctx->ipad , 0x36, 128 );
00418     memset( ctx->opad , 0x5C, 128 );
00419 
00420     for( i = 0; i < keylen; i++ )
00421     {
00422         ctx->ipad [i] = (unsigned char)( ctx->ipad [i] ^ key[i] );
00423         ctx->opad [i] = (unsigned char)( ctx->opad [i] ^ key[i] );
00424     }
00425 
00426     sha512_starts( ctx, is384 );
00427     sha512_update( ctx, ctx->ipad , 128 );
00428 
00429     polarssl_zeroize( sum, sizeof( sum ) );
00430 }
00431 
00432 /*
00433  * SHA-512 HMAC process buffer
00434  */
00435 void sha512_hmac_update( sha512_context  *ctx,
00436                          const unsigned char *input, size_t ilen )
00437 {
00438     sha512_update( ctx, input, ilen );
00439 }
00440 
00441 /*
00442  * SHA-512 HMAC final digest
00443  */
00444 void sha512_hmac_finish( sha512_context *ctx, unsigned char output[64] )
00445 {
00446     int is384, hlen;
00447     unsigned char tmpbuf[64];
00448 
00449     is384 = ctx->is384 ;
00450     hlen = ( is384 == 0 ) ? 64 : 48;
00451 
00452     sha512_finish( ctx, tmpbuf );
00453     sha512_starts( ctx, is384 );
00454     sha512_update( ctx, ctx->opad , 128 );
00455     sha512_update( ctx, tmpbuf, hlen );
00456     sha512_finish( ctx, output );
00457 
00458     polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
00459 }
00460 
00461 /*
00462  * SHA-512 HMAC context reset
00463  */
00464 void sha512_hmac_reset( sha512_context *ctx )
00465 {
00466     sha512_starts( ctx, ctx->is384  );
00467     sha512_update( ctx, ctx->ipad , 128 );
00468 }
00469 
00470 /*
00471  * output = HMAC-SHA-512( hmac key, input buffer )
00472  */
00473 void sha512_hmac( const unsigned char *key, size_t keylen,
00474                 const unsigned char *input, size_t ilen,
00475                 unsigned char output[64], int is384 )
00476 {
00477     sha512_context ctx;
00478 
00479     sha512_init( &ctx );
00480     sha512_hmac_starts( &ctx, key, keylen, is384 );
00481     sha512_hmac_update( &ctx, input, ilen );
00482     sha512_hmac_finish( &ctx, output );
00483     sha512_free( &ctx );
00484 }
00485 
00486 #if defined(POLARSSL_SELF_TEST)
00487 
00488 /*
00489  * FIPS-180-2 test vectors
00490  */
00491 static const unsigned char sha512_test_buf[3][113] =
00492 {
00493     { "abc" },
00494     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
00495       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
00496     { "" }
00497 };
00498 
00499 static const int sha512_test_buflen[3] =
00500 {
00501     3, 112, 1000
00502 };
00503 
00504 static const unsigned char sha512_test_sum[6][64] =
00505 {
00506     /*
00507      * SHA-384 test vectors
00508      */
00509     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
00510       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
00511       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
00512       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
00513       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
00514       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
00515     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
00516       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
00517       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
00518       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
00519       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
00520       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
00521     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
00522       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
00523       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
00524       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
00525       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
00526       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
00527 
00528     /*
00529      * SHA-512 test vectors
00530      */
00531     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
00532       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
00533       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
00534       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
00535       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
00536       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
00537       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
00538       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
00539     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
00540       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
00541       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
00542       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
00543       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
00544       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
00545       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
00546       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
00547     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
00548       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
00549       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
00550       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
00551       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
00552       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
00553       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
00554       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
00555 };
00556 
00557 /*
00558  * RFC 4231 test vectors
00559  */
00560 static const unsigned char sha512_hmac_test_key[7][26] =
00561 {
00562     { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
00563       "\x0B\x0B\x0B\x0B" },
00564     { "Jefe" },
00565     { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
00566       "\xAA\xAA\xAA\xAA" },
00567     { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
00568       "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
00569     { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
00570       "\x0C\x0C\x0C\x0C" },
00571     { "" }, /* 0xAA 131 times */
00572     { "" }
00573 };
00574 
00575 static const int sha512_hmac_test_keylen[7] =
00576 {
00577     20, 4, 20, 25, 20, 131, 131
00578 };
00579 
00580 static const unsigned char sha512_hmac_test_buf[7][153] =
00581 {
00582     { "Hi There" },
00583     { "what do ya want for nothing?" },
00584     { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00585       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00586       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00587       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00588       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
00589     { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00590       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00591       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00592       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00593       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
00594     { "Test With Truncation" },
00595     { "Test Using Larger Than Block-Size Key - Hash Key First" },
00596     { "This is a test using a larger than block-size key "
00597       "and a larger than block-size data. The key needs to "
00598       "be hashed before being used by the HMAC algorithm." }
00599 };
00600 
00601 static const int sha512_hmac_test_buflen[7] =
00602 {
00603     8, 28, 50, 50, 20, 54, 152
00604 };
00605 
00606 static const unsigned char sha512_hmac_test_sum[14][64] =
00607 {
00608     /*
00609      * HMAC-SHA-384 test vectors
00610      */
00611     { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
00612       0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
00613       0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
00614       0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
00615       0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
00616       0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
00617     { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
00618       0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
00619       0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
00620       0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
00621       0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
00622       0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
00623     { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
00624       0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
00625       0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
00626       0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
00627       0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
00628       0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
00629     { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
00630       0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
00631       0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
00632       0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
00633       0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
00634       0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
00635     { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
00636       0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
00637     { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
00638       0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
00639       0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
00640       0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
00641       0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
00642       0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
00643     { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
00644       0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
00645       0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
00646       0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
00647       0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
00648       0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
00649 
00650     /*
00651      * HMAC-SHA-512 test vectors
00652      */
00653     { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
00654       0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
00655       0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
00656       0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
00657       0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
00658       0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
00659       0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
00660       0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
00661     { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
00662       0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
00663       0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
00664       0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
00665       0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
00666       0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
00667       0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
00668       0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
00669     { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
00670       0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
00671       0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
00672       0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
00673       0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
00674       0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
00675       0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
00676       0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
00677     { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
00678       0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
00679       0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
00680       0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
00681       0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
00682       0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
00683       0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
00684       0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
00685     { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
00686       0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
00687     { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
00688       0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
00689       0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
00690       0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
00691       0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
00692       0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
00693       0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
00694       0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
00695     { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
00696       0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
00697       0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
00698       0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
00699       0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
00700       0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
00701       0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
00702       0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
00703 };
00704 
00705 /*
00706  * Checkup routine
00707  */
00708 int sha512_self_test( int verbose )
00709 {
00710     int i, j, k, buflen, ret = 0;
00711     unsigned char buf[1024];
00712     unsigned char sha512sum[64];
00713     sha512_context ctx;
00714 
00715     sha512_init( &ctx );
00716 
00717     for( i = 0; i < 6; i++ )
00718     {
00719         j = i % 3;
00720         k = i < 3;
00721 
00722         if( verbose != 0 )
00723             polarssl_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
00724 
00725         sha512_starts( &ctx, k );
00726 
00727         if( j == 2 )
00728         {
00729             memset( buf, 'a', buflen = 1000 );
00730 
00731             for( j = 0; j < 1000; j++ )
00732                 sha512_update( &ctx, buf, buflen );
00733         }
00734         else
00735             sha512_update( &ctx, sha512_test_buf[j],
00736                                  sha512_test_buflen[j] );
00737 
00738         sha512_finish( &ctx, sha512sum );
00739 
00740         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
00741         {
00742             if( verbose != 0 )
00743                 polarssl_printf( "failed\n" );
00744 
00745             ret = 1;
00746             goto exit;
00747         }
00748 
00749         if( verbose != 0 )
00750             polarssl_printf( "passed\n" );
00751     }
00752 
00753     if( verbose != 0 )
00754         polarssl_printf( "\n" );
00755 
00756     for( i = 0; i < 14; i++ )
00757     {
00758         j = i % 7;
00759         k = i < 7;
00760 
00761         if( verbose != 0 )
00762             polarssl_printf( "  HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 );
00763 
00764         if( j == 5 || j == 6 )
00765         {
00766             memset( buf, 0xAA, buflen = 131 );
00767             sha512_hmac_starts( &ctx, buf, buflen, k );
00768         }
00769         else
00770             sha512_hmac_starts( &ctx, sha512_hmac_test_key[j],
00771                                       sha512_hmac_test_keylen[j], k );
00772 
00773         sha512_hmac_update( &ctx, sha512_hmac_test_buf[j],
00774                                   sha512_hmac_test_buflen[j] );
00775 
00776         sha512_hmac_finish( &ctx, sha512sum );
00777 
00778         buflen = ( j == 4 ) ? 16 : 64 - k * 16;
00779 
00780         if( memcmp( sha512sum, sha512_hmac_test_sum[i], buflen ) != 0 )
00781         {
00782             if( verbose != 0 )
00783                 polarssl_printf( "failed\n" );
00784 
00785             ret = 1;
00786             goto exit;
00787         }
00788 
00789         if( verbose != 0 )
00790             polarssl_printf( "passed\n" );
00791     }
00792 
00793     if( verbose != 0 )
00794         polarssl_printf( "\n" );
00795 
00796 exit:
00797     sha512_free( &ctx );
00798 
00799     return( ret );
00800 }
00801 
00802 #endif /* POLARSSL_SELF_TEST */
00803 
00804 #endif /* POLARSSL_SHA512_C */
00805