1 /* 2 * FIPS-180-2 compliant SHA-384/512 implementation 3 * 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5 * SPDX-License-Identifier: Apache-2.0 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 * not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * This file is part of mbed TLS (https://tls.mbed.org) 20 */ 21 /* 22 * The SHA-512 Secure Hash Standard was published by NIST in 2002. 23 * 24 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf 25 */ 26 27 #if !defined(MBEDTLS_CONFIG_FILE) 28 #include "mbedtls/config.h" 29 #else 30 #include MBEDTLS_CONFIG_FILE 31 #endif 32 33 #if defined(MBEDTLS_SHA512_C) 34 35 #include "mbedtls/sha512.h" 36 37 #if defined(_MSC_VER) || defined(__WATCOMC__) 38 #define UL64(x) x##ui64 39 #else 40 #define UL64(x) x##ULL 41 #endif 42 43 #include <string.h> 44 45 #if defined(MBEDTLS_SELF_TEST) 46 #if defined(MBEDTLS_PLATFORM_C) 47 #include "mbedtls/platform.h" 48 #else 49 #include <stdio.h> 50 #include <stdlib.h> 51 #define mbedtls_printf printf 52 #define mbedtls_calloc calloc 53 #define mbedtls_free free 54 #endif /* MBEDTLS_PLATFORM_C */ 55 #endif /* MBEDTLS_SELF_TEST */ 56 57 #if !defined(MBEDTLS_SHA512_ALT) 58 59 /* Implementation that should never be optimized out by the compiler */ 60 static void mbedtls_zeroize( void *v, size_t n ) { 61 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 62 } 63 64 /* 65 * 64-bit integer manipulation macros (big endian) 66 */ 67 #ifndef GET_UINT64_BE 68 #define GET_UINT64_BE(n,b,i) \ 69 { \ 70 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ 71 | ( (uint64_t) (b)[(i) + 1] << 48 ) \ 72 | ( (uint64_t) (b)[(i) + 2] << 40 ) \ 73 | ( (uint64_t) (b)[(i) + 3] << 32 ) \ 74 | ( (uint64_t) (b)[(i) + 4] << 24 ) \ 75 | ( (uint64_t) (b)[(i) + 5] << 16 ) \ 76 | ( (uint64_t) (b)[(i) + 6] << 8 ) \ 77 | ( (uint64_t) (b)[(i) + 7] ); \ 78 } 79 #endif /* GET_UINT64_BE */ 80 81 #ifndef PUT_UINT64_BE 82 #define PUT_UINT64_BE(n,b,i) \ 83 { \ 84 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ 85 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ 86 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ 87 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ 88 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ 89 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ 90 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ 91 (b)[(i) + 7] = (unsigned char) ( (n) ); \ 92 } 93 #endif /* PUT_UINT64_BE */ 94 95 void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) 96 { 97 memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); 98 } 99 100 void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) 101 { 102 if( ctx == NULL ) 103 return; 104 105 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); 106 } 107 108 void mbedtls_sha512_clone( mbedtls_sha512_context *dst, 109 const mbedtls_sha512_context *src ) 110 { 111 *dst = *src; 112 } 113 114 /* 115 * SHA-512 context setup 116 */ 117 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 ) 118 { 119 ctx->total[0] = 0; 120 ctx->total[1] = 0; 121 122 if( is384 == 0 ) 123 { 124 /* SHA-512 */ 125 ctx->state[0] = UL64(0x6A09E667F3BCC908); 126 ctx->state[1] = UL64(0xBB67AE8584CAA73B); 127 ctx->state[2] = UL64(0x3C6EF372FE94F82B); 128 ctx->state[3] = UL64(0xA54FF53A5F1D36F1); 129 ctx->state[4] = UL64(0x510E527FADE682D1); 130 ctx->state[5] = UL64(0x9B05688C2B3E6C1F); 131 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); 132 ctx->state[7] = UL64(0x5BE0CD19137E2179); 133 } 134 else 135 { 136 /* SHA-384 */ 137 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); 138 ctx->state[1] = UL64(0x629A292A367CD507); 139 ctx->state[2] = UL64(0x9159015A3070DD17); 140 ctx->state[3] = UL64(0x152FECD8F70E5939); 141 ctx->state[4] = UL64(0x67332667FFC00B31); 142 ctx->state[5] = UL64(0x8EB44A8768581511); 143 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); 144 ctx->state[7] = UL64(0x47B5481DBEFA4FA4); 145 } 146 147 ctx->is384 = is384; 148 } 149 150 #if !defined(MBEDTLS_SHA512_PROCESS_ALT) 151 152 /* 153 * Round constants 154 */ 155 static const uint64_t K[80] = 156 { 157 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), 158 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), 159 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), 160 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), 161 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), 162 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), 163 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), 164 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), 165 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), 166 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), 167 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), 168 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), 169 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), 170 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), 171 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), 172 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), 173 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), 174 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), 175 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), 176 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), 177 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), 178 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), 179 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), 180 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), 181 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), 182 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), 183 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), 184 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), 185 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), 186 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), 187 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), 188 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), 189 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), 190 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), 191 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), 192 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), 193 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), 194 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), 195 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), 196 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) 197 }; 198 199 void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) 200 { 201 int i; 202 uint64_t temp1, temp2, W[80]; 203 uint64_t A, B, C, D, E, F, G, H; 204 205 #define SHR(x,n) (x >> n) 206 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) 207 208 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) 209 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) 210 211 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) 212 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) 213 214 #define F0(x,y,z) ((x & y) | (z & (x | y))) 215 #define F1(x,y,z) (z ^ (x & (y ^ z))) 216 217 #define P(a,b,c,d,e,f,g,h,x,K) \ 218 { \ 219 temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 220 temp2 = S2(a) + F0(a,b,c); \ 221 d += temp1; h = temp1 + temp2; \ 222 } 223 224 for( i = 0; i < 16; i++ ) 225 { 226 GET_UINT64_BE( W[i], data, i << 3 ); 227 } 228 229 for( ; i < 80; i++ ) 230 { 231 W[i] = S1(W[i - 2]) + W[i - 7] + 232 S0(W[i - 15]) + W[i - 16]; 233 } 234 235 A = ctx->state[0]; 236 B = ctx->state[1]; 237 C = ctx->state[2]; 238 D = ctx->state[3]; 239 E = ctx->state[4]; 240 F = ctx->state[5]; 241 G = ctx->state[6]; 242 H = ctx->state[7]; 243 i = 0; 244 245 do 246 { 247 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; 248 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; 249 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; 250 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; 251 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; 252 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; 253 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; 254 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; 255 } 256 while( i < 80 ); 257 258 ctx->state[0] += A; 259 ctx->state[1] += B; 260 ctx->state[2] += C; 261 ctx->state[3] += D; 262 ctx->state[4] += E; 263 ctx->state[5] += F; 264 ctx->state[6] += G; 265 ctx->state[7] += H; 266 } 267 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */ 268 269 /* 270 * SHA-512 process buffer 271 */ 272 void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input, 273 size_t ilen ) 274 { 275 size_t fill; 276 unsigned int left; 277 278 if( ilen == 0 ) 279 return; 280 281 left = (unsigned int) (ctx->total[0] & 0x7F); 282 fill = 128 - left; 283 284 ctx->total[0] += (uint64_t) ilen; 285 286 if( ctx->total[0] < (uint64_t) ilen ) 287 ctx->total[1]++; 288 289 if( left && ilen >= fill ) 290 { 291 memcpy( (void *) (ctx->buffer + left), input, fill ); 292 mbedtls_sha512_process( ctx, ctx->buffer ); 293 input += fill; 294 ilen -= fill; 295 left = 0; 296 } 297 298 while( ilen >= 128 ) 299 { 300 mbedtls_sha512_process( ctx, input ); 301 input += 128; 302 ilen -= 128; 303 } 304 305 if( ilen > 0 ) 306 memcpy( (void *) (ctx->buffer + left), input, ilen ); 307 } 308 309 static const unsigned char sha512_padding[128] = 310 { 311 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 315 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 319 }; 320 321 /* 322 * SHA-512 final digest 323 */ 324 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] ) 325 { 326 size_t last, padn; 327 uint64_t high, low; 328 unsigned char msglen[16]; 329 330 high = ( ctx->total[0] >> 61 ) 331 | ( ctx->total[1] << 3 ); 332 low = ( ctx->total[0] << 3 ); 333 334 PUT_UINT64_BE( high, msglen, 0 ); 335 PUT_UINT64_BE( low, msglen, 8 ); 336 337 last = (size_t)( ctx->total[0] & 0x7F ); 338 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); 339 340 mbedtls_sha512_update( ctx, sha512_padding, padn ); 341 mbedtls_sha512_update( ctx, msglen, 16 ); 342 343 PUT_UINT64_BE( ctx->state[0], output, 0 ); 344 PUT_UINT64_BE( ctx->state[1], output, 8 ); 345 PUT_UINT64_BE( ctx->state[2], output, 16 ); 346 PUT_UINT64_BE( ctx->state[3], output, 24 ); 347 PUT_UINT64_BE( ctx->state[4], output, 32 ); 348 PUT_UINT64_BE( ctx->state[5], output, 40 ); 349 350 if( ctx->is384 == 0 ) 351 { 352 PUT_UINT64_BE( ctx->state[6], output, 48 ); 353 PUT_UINT64_BE( ctx->state[7], output, 56 ); 354 } 355 } 356 357 #endif /* !MBEDTLS_SHA512_ALT */ 358 359 /* 360 * output = SHA-512( input buffer ) 361 */ 362 void mbedtls_sha512( const unsigned char *input, size_t ilen, 363 unsigned char output[64], int is384 ) 364 { 365 mbedtls_sha512_context ctx; 366 367 mbedtls_sha512_init( &ctx ); 368 mbedtls_sha512_starts( &ctx, is384 ); 369 mbedtls_sha512_update( &ctx, input, ilen ); 370 mbedtls_sha512_finish( &ctx, output ); 371 mbedtls_sha512_free( &ctx ); 372 } 373 374 #if defined(MBEDTLS_SELF_TEST) 375 376 /* 377 * FIPS-180-2 test vectors 378 */ 379 static const unsigned char sha512_test_buf[3][113] = 380 { 381 { "abc" }, 382 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" 383 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, 384 { "" } 385 }; 386 387 static const int sha512_test_buflen[3] = 388 { 389 3, 112, 1000 390 }; 391 392 static const unsigned char sha512_test_sum[6][64] = 393 { 394 /* 395 * SHA-384 test vectors 396 */ 397 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, 398 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, 399 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, 400 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, 401 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, 402 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, 403 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, 404 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, 405 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, 406 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, 407 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, 408 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, 409 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, 410 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, 411 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, 412 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, 413 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, 414 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, 415 416 /* 417 * SHA-512 test vectors 418 */ 419 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, 420 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, 421 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, 422 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, 423 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, 424 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, 425 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, 426 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, 427 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, 428 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, 429 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, 430 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, 431 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, 432 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, 433 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, 434 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, 435 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, 436 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, 437 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, 438 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, 439 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, 440 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, 441 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, 442 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } 443 }; 444 445 /* 446 * Checkup routine 447 */ 448 int mbedtls_sha512_self_test( int verbose ) 449 { 450 int i, j, k, buflen, ret = 0; 451 unsigned char *buf; 452 unsigned char sha512sum[64]; 453 mbedtls_sha512_context ctx; 454 455 buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); 456 if( NULL == buf ) 457 { 458 if( verbose != 0 ) 459 mbedtls_printf( "Buffer allocation failed\n" ); 460 461 return( 1 ); 462 } 463 464 mbedtls_sha512_init( &ctx ); 465 466 for( i = 0; i < 6; i++ ) 467 { 468 j = i % 3; 469 k = i < 3; 470 471 if( verbose != 0 ) 472 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); 473 474 mbedtls_sha512_starts( &ctx, k ); 475 476 if( j == 2 ) 477 { 478 memset( buf, 'a', buflen = 1000 ); 479 480 for( j = 0; j < 1000; j++ ) 481 mbedtls_sha512_update( &ctx, buf, buflen ); 482 } 483 else 484 mbedtls_sha512_update( &ctx, sha512_test_buf[j], 485 sha512_test_buflen[j] ); 486 487 mbedtls_sha512_finish( &ctx, sha512sum ); 488 489 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) 490 { 491 if( verbose != 0 ) 492 mbedtls_printf( "failed\n" ); 493 494 ret = 1; 495 goto exit; 496 } 497 498 if( verbose != 0 ) 499 mbedtls_printf( "passed\n" ); 500 } 501 502 if( verbose != 0 ) 503 mbedtls_printf( "\n" ); 504 505 exit: 506 mbedtls_sha512_free( &ctx ); 507 mbedtls_free( buf ); 508 509 return( ret ); 510 } 511 512 #endif /* MBEDTLS_SELF_TEST */ 513 514 #endif /* MBEDTLS_SHA512_C */ 515