Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

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