Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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