Knight KE / Mbed OS Game_Master
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-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 /*
00022  *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
00023  *
00024  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
00025  */
00026 
00027 #if !defined(MBEDTLS_CONFIG_FILE)
00028 #include "mbedtls/config.h"
00029 #else
00030 #include MBEDTLS_CONFIG_FILE
00031 #endif
00032 
00033 #if defined(MBEDTLS_SHA512_C)
00034 
00035 #include "mbedtls/sha512.h"
00036 #include "mbedtls/platform_util.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(MBEDTLS_SELF_TEST)
00047 #if defined(MBEDTLS_PLATFORM_C)
00048 #include "mbedtls/platform.h"
00049 #else
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052 #define mbedtls_printf printf
00053 #define mbedtls_calloc    calloc
00054 #define mbedtls_free       free
00055 #endif /* MBEDTLS_PLATFORM_C */
00056 #endif /* MBEDTLS_SELF_TEST */
00057 
00058 #if !defined(MBEDTLS_SHA512_ALT)
00059 
00060 /*
00061  * 64-bit integer manipulation macros (big endian)
00062  */
00063 #ifndef GET_UINT64_BE
00064 #define GET_UINT64_BE(n,b,i)                            \
00065 {                                                       \
00066     (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
00067         | ( (uint64_t) (b)[(i) + 1] << 48 )       \
00068         | ( (uint64_t) (b)[(i) + 2] << 40 )       \
00069         | ( (uint64_t) (b)[(i) + 3] << 32 )       \
00070         | ( (uint64_t) (b)[(i) + 4] << 24 )       \
00071         | ( (uint64_t) (b)[(i) + 5] << 16 )       \
00072         | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
00073         | ( (uint64_t) (b)[(i) + 7]       );      \
00074 }
00075 #endif /* GET_UINT64_BE */
00076 
00077 #ifndef PUT_UINT64_BE
00078 #define PUT_UINT64_BE(n,b,i)                            \
00079 {                                                       \
00080     (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
00081     (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
00082     (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
00083     (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
00084     (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
00085     (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
00086     (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
00087     (b)[(i) + 7] = (unsigned char) ( (n)       );       \
00088 }
00089 #endif /* PUT_UINT64_BE */
00090 
00091 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
00092 {
00093     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
00094 }
00095 
00096 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
00097 {
00098     if( ctx == NULL )
00099         return;
00100 
00101     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
00102 }
00103 
00104 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
00105                            const mbedtls_sha512_context *src )
00106 {
00107     *dst = *src;
00108 }
00109 
00110 /*
00111  * SHA-512 context setup
00112  */
00113 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
00114 {
00115     ctx->total [0] = 0;
00116     ctx->total [1] = 0;
00117 
00118     if( is384 == 0 )
00119     {
00120         /* SHA-512 */
00121         ctx->state [0] = UL64(0x6A09E667F3BCC908);
00122         ctx->state [1] = UL64(0xBB67AE8584CAA73B);
00123         ctx->state [2] = UL64(0x3C6EF372FE94F82B);
00124         ctx->state [3] = UL64(0xA54FF53A5F1D36F1);
00125         ctx->state [4] = UL64(0x510E527FADE682D1);
00126         ctx->state [5] = UL64(0x9B05688C2B3E6C1F);
00127         ctx->state [6] = UL64(0x1F83D9ABFB41BD6B);
00128         ctx->state [7] = UL64(0x5BE0CD19137E2179);
00129     }
00130     else
00131     {
00132         /* SHA-384 */
00133         ctx->state [0] = UL64(0xCBBB9D5DC1059ED8);
00134         ctx->state [1] = UL64(0x629A292A367CD507);
00135         ctx->state [2] = UL64(0x9159015A3070DD17);
00136         ctx->state [3] = UL64(0x152FECD8F70E5939);
00137         ctx->state [4] = UL64(0x67332667FFC00B31);
00138         ctx->state [5] = UL64(0x8EB44A8768581511);
00139         ctx->state [6] = UL64(0xDB0C2E0D64F98FA7);
00140         ctx->state [7] = UL64(0x47B5481DBEFA4FA4);
00141     }
00142 
00143     ctx->is384  = is384;
00144 
00145     return( 0 );
00146 }
00147 
00148 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00149 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
00150                             int is384 )
00151 {
00152     mbedtls_sha512_starts_ret( ctx, is384 );
00153 }
00154 #endif
00155 
00156 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
00157 
00158 /*
00159  * Round constants
00160  */
00161 static const uint64_t K[80] =
00162 {
00163     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
00164     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
00165     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
00166     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
00167     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
00168     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
00169     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
00170     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
00171     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
00172     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
00173     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
00174     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
00175     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
00176     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
00177     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
00178     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
00179     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
00180     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
00181     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
00182     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
00183     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
00184     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
00185     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
00186     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
00187     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
00188     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
00189     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
00190     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
00191     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
00192     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
00193     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
00194     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
00195     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
00196     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
00197     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
00198     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
00199     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
00200     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
00201     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
00202     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
00203 };
00204 
00205 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
00206                                      const unsigned char data[128] )
00207 {
00208     int i;
00209     uint64_t temp1, temp2, W[80];
00210     uint64_t A, B, C, D, E, F, G, H;
00211 
00212 #define  SHR(x,n) (x >> n)
00213 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
00214 
00215 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
00216 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
00217 
00218 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
00219 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
00220 
00221 #define F0(x,y,z) ((x & y) | (z & (x | y)))
00222 #define F1(x,y,z) (z ^ (x & (y ^ z)))
00223 
00224 #define P(a,b,c,d,e,f,g,h,x,K)                  \
00225 {                                               \
00226     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
00227     temp2 = S2(a) + F0(a,b,c);                  \
00228     d += temp1; h = temp1 + temp2;              \
00229 }
00230 
00231     for( i = 0; i < 16; i++ )
00232     {
00233         GET_UINT64_BE( W[i], data, i << 3 );
00234     }
00235 
00236     for( ; i < 80; i++ )
00237     {
00238         W[i] = S1(W[i -  2]) + W[i -  7] +
00239                S0(W[i - 15]) + W[i - 16];
00240     }
00241 
00242     A = ctx->state [0];
00243     B = ctx->state [1];
00244     C = ctx->state [2];
00245     D = ctx->state [3];
00246     E = ctx->state [4];
00247     F = ctx->state [5];
00248     G = ctx->state [6];
00249     H = ctx->state [7];
00250     i = 0;
00251 
00252     do
00253     {
00254         P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
00255         P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
00256         P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
00257         P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
00258         P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
00259         P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
00260         P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
00261         P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
00262     }
00263     while( i < 80 );
00264 
00265     ctx->state [0] += A;
00266     ctx->state [1] += B;
00267     ctx->state [2] += C;
00268     ctx->state [3] += D;
00269     ctx->state [4] += E;
00270     ctx->state [5] += F;
00271     ctx->state [6] += G;
00272     ctx->state [7] += H;
00273 
00274     return( 0 );
00275 }
00276 
00277 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00278 void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
00279                              const unsigned char data[128] )
00280 {
00281     mbedtls_internal_sha512_process( ctx, data );
00282 }
00283 #endif
00284 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
00285 
00286 /*
00287  * SHA-512 process buffer
00288  */
00289 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
00290                                const unsigned char *input,
00291                                size_t ilen )
00292 {
00293     int ret;
00294     size_t fill;
00295     unsigned int left;
00296 
00297     if( ilen == 0 )
00298         return( 0 );
00299 
00300     left = (unsigned int) (ctx->total [0] & 0x7F);
00301     fill = 128 - left;
00302 
00303     ctx->total [0] += (uint64_t) ilen;
00304 
00305     if( ctx->total [0] < (uint64_t) ilen )
00306         ctx->total [1]++;
00307 
00308     if( left && ilen >= fill )
00309     {
00310         memcpy( (void *) (ctx->buffer  + left), input, fill );
00311 
00312         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer  ) ) != 0 )
00313             return( ret );
00314 
00315         input += fill;
00316         ilen  -= fill;
00317         left = 0;
00318     }
00319 
00320     while( ilen >= 128 )
00321     {
00322         if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
00323             return( ret );
00324 
00325         input += 128;
00326         ilen  -= 128;
00327     }
00328 
00329     if( ilen > 0 )
00330         memcpy( (void *) (ctx->buffer  + left), input, ilen );
00331 
00332     return( 0 );
00333 }
00334 
00335 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00336 void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
00337                             const unsigned char *input,
00338                             size_t ilen )
00339 {
00340     mbedtls_sha512_update_ret( ctx, input, ilen );
00341 }
00342 #endif
00343 
00344 static const unsigned char sha512_padding[128] =
00345 {
00346  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00347     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00348     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00349     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00350     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00351     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00352     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00353     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00354 };
00355 
00356 /*
00357  * SHA-512 final digest
00358  */
00359 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
00360                                unsigned char output[64] )
00361 {
00362     int ret;
00363     size_t last, padn;
00364     uint64_t high, low;
00365     unsigned char msglen[16];
00366 
00367     high = ( ctx->total [0] >> 61 )
00368          | ( ctx->total [1] <<  3 );
00369     low  = ( ctx->total [0] <<  3 );
00370 
00371     PUT_UINT64_BE( high, msglen, 0 );
00372     PUT_UINT64_BE( low,  msglen, 8 );
00373 
00374     last = (size_t)( ctx->total [0] & 0x7F );
00375     padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
00376 
00377     if( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 )
00378             return( ret );
00379 
00380     if( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 )
00381             return( ret );
00382 
00383     PUT_UINT64_BE( ctx->state [0], output,  0 );
00384     PUT_UINT64_BE( ctx->state [1], output,  8 );
00385     PUT_UINT64_BE( ctx->state [2], output, 16 );
00386     PUT_UINT64_BE( ctx->state [3], output, 24 );
00387     PUT_UINT64_BE( ctx->state [4], output, 32 );
00388     PUT_UINT64_BE( ctx->state [5], output, 40 );
00389 
00390     if( ctx->is384  == 0 )
00391     {
00392         PUT_UINT64_BE( ctx->state [6], output, 48 );
00393         PUT_UINT64_BE( ctx->state [7], output, 56 );
00394     }
00395 
00396     return( 0 );
00397 }
00398 
00399 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00400 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
00401                             unsigned char output[64] )
00402 {
00403     mbedtls_sha512_finish_ret( ctx, output );
00404 }
00405 #endif
00406 
00407 #endif /* !MBEDTLS_SHA512_ALT */
00408 
00409 /*
00410  * output = SHA-512( input buffer )
00411  */
00412 int mbedtls_sha512_ret( const unsigned char *input,
00413                     size_t ilen,
00414                     unsigned char output[64],
00415                     int is384 )
00416 {
00417     int ret;
00418     mbedtls_sha512_context ctx;
00419 
00420     mbedtls_sha512_init( &ctx );
00421 
00422     if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
00423         goto exit;
00424 
00425     if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
00426         goto exit;
00427 
00428     if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
00429         goto exit;
00430 
00431 exit:
00432     mbedtls_sha512_free( &ctx );
00433 
00434     return( ret );
00435 }
00436 
00437 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00438 void mbedtls_sha512( const unsigned char *input,
00439                      size_t ilen,
00440                      unsigned char output[64],
00441                      int is384 )
00442 {
00443     mbedtls_sha512_ret( input, ilen, output, is384 );
00444 }
00445 #endif
00446 
00447 #if defined(MBEDTLS_SELF_TEST)
00448 
00449 /*
00450  * FIPS-180-2 test vectors
00451  */
00452 static const unsigned char sha512_test_buf[3][113] =
00453 {
00454     { "abc" },
00455     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
00456       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
00457     { "" }
00458 };
00459 
00460 static const size_t sha512_test_buflen[3] =
00461 {
00462     3, 112, 1000
00463 };
00464 
00465 static const unsigned char sha512_test_sum[6][64] =
00466 {
00467     /*
00468      * SHA-384 test vectors
00469      */
00470     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
00471       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
00472       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
00473       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
00474       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
00475       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
00476     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
00477       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
00478       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
00479       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
00480       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
00481       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
00482     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
00483       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
00484       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
00485       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
00486       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
00487       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
00488 
00489     /*
00490      * SHA-512 test vectors
00491      */
00492     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
00493       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
00494       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
00495       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
00496       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
00497       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
00498       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
00499       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
00500     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
00501       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
00502       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
00503       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
00504       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
00505       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
00506       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
00507       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
00508     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
00509       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
00510       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
00511       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
00512       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
00513       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
00514       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
00515       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
00516 };
00517 
00518 /*
00519  * Checkup routine
00520  */
00521 int mbedtls_sha512_self_test( int verbose )
00522 {
00523     int i, j, k, buflen, ret = 0;
00524     unsigned char *buf;
00525     unsigned char sha512sum[64];
00526     mbedtls_sha512_context ctx;
00527 
00528     buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
00529     if( NULL == buf )
00530     {
00531         if( verbose != 0 )
00532             mbedtls_printf( "Buffer allocation failed\n" );
00533 
00534         return( 1 );
00535     }
00536 
00537     mbedtls_sha512_init( &ctx );
00538 
00539     for( i = 0; i < 6; i++ )
00540     {
00541         j = i % 3;
00542         k = i < 3;
00543 
00544         if( verbose != 0 )
00545             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
00546 
00547         if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
00548             goto fail;
00549 
00550         if( j == 2 )
00551         {
00552             memset( buf, 'a', buflen = 1000 );
00553 
00554             for( j = 0; j < 1000; j++ )
00555             {
00556                 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
00557                 if( ret != 0 )
00558                     goto fail;
00559             }
00560         }
00561         else
00562         {
00563             ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
00564                                              sha512_test_buflen[j] );
00565             if( ret != 0 )
00566                 goto fail;
00567         }
00568 
00569         if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
00570             goto fail;
00571 
00572         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
00573         {
00574             ret = 1;
00575             goto fail;
00576         }
00577 
00578         if( verbose != 0 )
00579             mbedtls_printf( "passed\n" );
00580     }
00581 
00582     if( verbose != 0 )
00583         mbedtls_printf( "\n" );
00584 
00585     goto exit;
00586 
00587 fail:
00588     if( verbose != 0 )
00589         mbedtls_printf( "failed\n" );
00590 
00591 exit:
00592     mbedtls_sha512_free( &ctx );
00593     mbedtls_free( buf );
00594 
00595     return( ret );
00596 }
00597 
00598 #endif /* MBEDTLS_SELF_TEST */
00599 
00600 #endif /* MBEDTLS_SHA512_C */