Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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 #define SHA512_VALIDATE_RET(cond)                           \
00059     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
00060 #define SHA512_VALIDATE(cond)  MBEDTLS_INTERNAL_VALIDATE( cond )
00061 
00062 #if !defined(MBEDTLS_SHA512_ALT)
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 #if defined(MBEDTLS_SHA512_SMALLER)
00096 static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
00097 {
00098     PUT_UINT64_BE(n, b, i);
00099 }
00100 #else
00101 #define sha512_put_uint64_be    PUT_UINT64_BE
00102 #endif /* MBEDTLS_SHA512_SMALLER */
00103 
00104 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
00105 {
00106     SHA512_VALIDATE( ctx != NULL );
00107 
00108     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
00109 }
00110 
00111 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
00112 {
00113     if( ctx == NULL )
00114         return;
00115 
00116     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
00117 }
00118 
00119 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
00120                            const mbedtls_sha512_context *src )
00121 {
00122     SHA512_VALIDATE( dst != NULL );
00123     SHA512_VALIDATE( src != NULL );
00124 
00125     *dst = *src;
00126 }
00127 
00128 /*
00129  * SHA-512 context setup
00130  */
00131 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
00132 {
00133     SHA512_VALIDATE_RET( ctx != NULL );
00134     SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
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     return( 0 );
00167 }
00168 
00169 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00170 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
00171                             int is384 )
00172 {
00173     mbedtls_sha512_starts_ret( ctx, is384 );
00174 }
00175 #endif
00176 
00177 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
00178 
00179 /*
00180  * Round constants
00181  */
00182 static const uint64_t K[80] =
00183 {
00184     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
00185     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
00186     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
00187     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
00188     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
00189     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
00190     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
00191     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
00192     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
00193     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
00194     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
00195     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
00196     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
00197     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
00198     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
00199     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
00200     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
00201     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
00202     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
00203     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
00204     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
00205     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
00206     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
00207     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
00208     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
00209     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
00210     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
00211     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
00212     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
00213     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
00214     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
00215     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
00216     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
00217     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
00218     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
00219     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
00220     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
00221     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
00222     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
00223     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
00224 };
00225 
00226 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
00227                                      const unsigned char data[128] )
00228 {
00229     int i;
00230     uint64_t temp1, temp2, W[80];
00231     uint64_t A[8];
00232 
00233     SHA512_VALIDATE_RET( ctx != NULL );
00234     SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
00235 
00236 #define  SHR(x,n) ((x) >> (n))
00237 #define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
00238 
00239 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
00240 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
00241 
00242 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
00243 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
00244 
00245 #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
00246 #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
00247 
00248 #define P(a,b,c,d,e,f,g,h,x,K)                                  \
00249     do                                                          \
00250     {                                                           \
00251         temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x);      \
00252         temp2 = S2(a) + F0((a),(b),(c));                        \
00253         (d) += temp1; (h) = temp1 + temp2;                      \
00254     } while( 0 )
00255 
00256     for( i = 0; i < 8; i++ )
00257         A[i] = ctx->state [i];
00258 
00259 #if defined(MBEDTLS_SHA512_SMALLER)
00260     for( i = 0; i < 80; i++ )
00261     {
00262         if( i < 16 )
00263         {
00264             GET_UINT64_BE( W[i], data, i << 3 );
00265         }
00266         else
00267         {
00268             W[i] = S1(W[i -  2]) + W[i -  7] +
00269                    S0(W[i - 15]) + W[i - 16];
00270         }
00271 
00272         P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
00273 
00274         temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
00275         A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
00276     }
00277 #else /* MBEDTLS_SHA512_SMALLER */
00278     for( i = 0; i < 16; i++ )
00279     {
00280         GET_UINT64_BE( W[i], data, i << 3 );
00281     }
00282 
00283     for( ; i < 80; i++ )
00284     {
00285         W[i] = S1(W[i -  2]) + W[i -  7] +
00286                S0(W[i - 15]) + W[i - 16];
00287     }
00288 
00289     i = 0;
00290     do
00291     {
00292         P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++;
00293         P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++;
00294         P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++;
00295         P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++;
00296         P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++;
00297         P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++;
00298         P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++;
00299         P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++;
00300     }
00301     while( i < 80 );
00302 #endif /* MBEDTLS_SHA512_SMALLER */
00303 
00304     for( i = 0; i < 8; i++ )
00305         ctx->state [i] += A[i];
00306 
00307     return( 0 );
00308 }
00309 
00310 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00311 void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
00312                              const unsigned char data[128] )
00313 {
00314     mbedtls_internal_sha512_process( ctx, data );
00315 }
00316 #endif
00317 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
00318 
00319 /*
00320  * SHA-512 process buffer
00321  */
00322 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
00323                                const unsigned char *input,
00324                                size_t ilen )
00325 {
00326     int ret;
00327     size_t fill;
00328     unsigned int left;
00329 
00330     SHA512_VALIDATE_RET( ctx != NULL );
00331     SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
00332 
00333     if( ilen == 0 )
00334         return( 0 );
00335 
00336     left = (unsigned int) (ctx->total [0] & 0x7F);
00337     fill = 128 - left;
00338 
00339     ctx->total [0] += (uint64_t) ilen;
00340 
00341     if( ctx->total [0] < (uint64_t) ilen )
00342         ctx->total [1]++;
00343 
00344     if( left && ilen >= fill )
00345     {
00346         memcpy( (void *) (ctx->buffer  + left), input, fill );
00347 
00348         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer  ) ) != 0 )
00349             return( ret );
00350 
00351         input += fill;
00352         ilen  -= fill;
00353         left = 0;
00354     }
00355 
00356     while( ilen >= 128 )
00357     {
00358         if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
00359             return( ret );
00360 
00361         input += 128;
00362         ilen  -= 128;
00363     }
00364 
00365     if( ilen > 0 )
00366         memcpy( (void *) (ctx->buffer  + left), input, ilen );
00367 
00368     return( 0 );
00369 }
00370 
00371 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00372 void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
00373                             const unsigned char *input,
00374                             size_t ilen )
00375 {
00376     mbedtls_sha512_update_ret( ctx, input, ilen );
00377 }
00378 #endif
00379 
00380 /*
00381  * SHA-512 final digest
00382  */
00383 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
00384                                unsigned char output[64] )
00385 {
00386     int ret;
00387     unsigned used;
00388     uint64_t high, low;
00389 
00390     SHA512_VALIDATE_RET( ctx != NULL );
00391     SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
00392 
00393     /*
00394      * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
00395      */
00396     used = ctx->total [0] & 0x7F;
00397 
00398     ctx->buffer [used++] = 0x80;
00399 
00400     if( used <= 112 )
00401     {
00402         /* Enough room for padding + length in current block */
00403         memset( ctx->buffer  + used, 0, 112 - used );
00404     }
00405     else
00406     {
00407         /* We'll need an extra block */
00408         memset( ctx->buffer  + used, 0, 128 - used );
00409 
00410         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer  ) ) != 0 )
00411             return( ret );
00412 
00413         memset( ctx->buffer , 0, 112 );
00414     }
00415 
00416     /*
00417      * Add message length
00418      */
00419     high = ( ctx->total [0] >> 61 )
00420          | ( ctx->total [1] <<  3 );
00421     low  = ( ctx->total [0] <<  3 );
00422 
00423     sha512_put_uint64_be( high, ctx->buffer , 112 );
00424     sha512_put_uint64_be( low,  ctx->buffer , 120 );
00425 
00426     if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer  ) ) != 0 )
00427         return( ret );
00428 
00429     /*
00430      * Output final state
00431      */
00432     sha512_put_uint64_be( ctx->state [0], output,  0 );
00433     sha512_put_uint64_be( ctx->state [1], output,  8 );
00434     sha512_put_uint64_be( ctx->state [2], output, 16 );
00435     sha512_put_uint64_be( ctx->state [3], output, 24 );
00436     sha512_put_uint64_be( ctx->state [4], output, 32 );
00437     sha512_put_uint64_be( ctx->state [5], output, 40 );
00438 
00439     if( ctx->is384  == 0 )
00440     {
00441         sha512_put_uint64_be( ctx->state [6], output, 48 );
00442         sha512_put_uint64_be( ctx->state [7], output, 56 );
00443     }
00444 
00445     return( 0 );
00446 }
00447 
00448 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00449 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
00450                             unsigned char output[64] )
00451 {
00452     mbedtls_sha512_finish_ret( ctx, output );
00453 }
00454 #endif
00455 
00456 #endif /* !MBEDTLS_SHA512_ALT */
00457 
00458 /*
00459  * output = SHA-512( input buffer )
00460  */
00461 int mbedtls_sha512_ret( const unsigned char *input,
00462                     size_t ilen,
00463                     unsigned char output[64],
00464                     int is384 )
00465 {
00466     int ret;
00467     mbedtls_sha512_context ctx;
00468 
00469     SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
00470     SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
00471     SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
00472 
00473     mbedtls_sha512_init( &ctx );
00474 
00475     if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
00476         goto exit;
00477 
00478     if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
00479         goto exit;
00480 
00481     if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
00482         goto exit;
00483 
00484 exit:
00485     mbedtls_sha512_free( &ctx );
00486 
00487     return( ret );
00488 }
00489 
00490 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00491 void mbedtls_sha512( const unsigned char *input,
00492                      size_t ilen,
00493                      unsigned char output[64],
00494                      int is384 )
00495 {
00496     mbedtls_sha512_ret( input, ilen, output, is384 );
00497 }
00498 #endif
00499 
00500 #if defined(MBEDTLS_SELF_TEST)
00501 
00502 /*
00503  * FIPS-180-2 test vectors
00504  */
00505 static const unsigned char sha512_test_buf[3][113] =
00506 {
00507     { "abc" },
00508     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
00509       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
00510     { "" }
00511 };
00512 
00513 static const size_t sha512_test_buflen[3] =
00514 {
00515     3, 112, 1000
00516 };
00517 
00518 static const unsigned char sha512_test_sum[6][64] =
00519 {
00520     /*
00521      * SHA-384 test vectors
00522      */
00523     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
00524       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
00525       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
00526       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
00527       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
00528       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
00529     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
00530       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
00531       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
00532       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
00533       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
00534       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
00535     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
00536       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
00537       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
00538       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
00539       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
00540       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
00541 
00542     /*
00543      * SHA-512 test vectors
00544      */
00545     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
00546       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
00547       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
00548       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
00549       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
00550       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
00551       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
00552       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
00553     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
00554       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
00555       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
00556       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
00557       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
00558       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
00559       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
00560       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
00561     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
00562       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
00563       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
00564       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
00565       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
00566       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
00567       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
00568       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
00569 };
00570 
00571 /*
00572  * Checkup routine
00573  */
00574 int mbedtls_sha512_self_test( int verbose )
00575 {
00576     int i, j, k, buflen, ret = 0;
00577     unsigned char *buf;
00578     unsigned char sha512sum[64];
00579     mbedtls_sha512_context ctx;
00580 
00581     buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
00582     if( NULL == buf )
00583     {
00584         if( verbose != 0 )
00585             mbedtls_printf( "Buffer allocation failed\n" );
00586 
00587         return( 1 );
00588     }
00589 
00590     mbedtls_sha512_init( &ctx );
00591 
00592     for( i = 0; i < 6; i++ )
00593     {
00594         j = i % 3;
00595         k = i < 3;
00596 
00597         if( verbose != 0 )
00598             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
00599 
00600         if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
00601             goto fail;
00602 
00603         if( j == 2 )
00604         {
00605             memset( buf, 'a', buflen = 1000 );
00606 
00607             for( j = 0; j < 1000; j++ )
00608             {
00609                 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
00610                 if( ret != 0 )
00611                     goto fail;
00612             }
00613         }
00614         else
00615         {
00616             ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
00617                                              sha512_test_buflen[j] );
00618             if( ret != 0 )
00619                 goto fail;
00620         }
00621 
00622         if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
00623             goto fail;
00624 
00625         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
00626         {
00627             ret = 1;
00628             goto fail;
00629         }
00630 
00631         if( verbose != 0 )
00632             mbedtls_printf( "passed\n" );
00633     }
00634 
00635     if( verbose != 0 )
00636         mbedtls_printf( "\n" );
00637 
00638     goto exit;
00639 
00640 fail:
00641     if( verbose != 0 )
00642         mbedtls_printf( "failed\n" );
00643 
00644 exit:
00645     mbedtls_sha512_free( &ctx );
00646     mbedtls_free( buf );
00647 
00648     return( ret );
00649 }
00650 
00651 #endif /* MBEDTLS_SELF_TEST */
00652 
00653 #endif /* MBEDTLS_SHA512_C */