1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * FIPS-180-2 compliant SHA-384/512 implementation 4 * 5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 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 #include "mbedtls/platform_util.h" 37 38 #if defined(_MSC_VER) || defined(__WATCOMC__) 39 #define UL64(x) x##ui64 40 #else 41 #define UL64(x) x##ULL 42 #endif 43 44 #include <string.h> 45 46 #if defined(MBEDTLS_SELF_TEST) 47 #if defined(MBEDTLS_PLATFORM_C) 48 #include "mbedtls/platform.h" 49 #else 50 #include <stdio.h> 51 #include <stdlib.h> 52 #define mbedtls_printf printf 53 #define mbedtls_calloc calloc 54 #define mbedtls_free free 55 #endif /* MBEDTLS_PLATFORM_C */ 56 #endif /* MBEDTLS_SELF_TEST */ 57 58 #define SHA512_VALIDATE_RET(cond) \ 59 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA ) 60 #define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) 61 62 #if !defined(MBEDTLS_SHA512_ALT) 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 SHA512_VALIDATE( ctx != NULL ); 98 99 memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); 100 } 101 102 void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) 103 { 104 if( ctx == NULL ) 105 return; 106 107 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); 108 } 109 110 void mbedtls_sha512_clone( mbedtls_sha512_context *dst, 111 const mbedtls_sha512_context *src ) 112 { 113 SHA512_VALIDATE( dst != NULL ); 114 SHA512_VALIDATE( src != NULL ); 115 116 *dst = *src; 117 } 118 119 /* 120 * SHA-512 context setup 121 */ 122 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ) 123 { 124 SHA512_VALIDATE_RET( ctx != NULL ); 125 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); 126 127 ctx->total[0] = 0; 128 ctx->total[1] = 0; 129 130 if( is384 == 0 ) 131 { 132 /* SHA-512 */ 133 ctx->state[0] = UL64(0x6A09E667F3BCC908); 134 ctx->state[1] = UL64(0xBB67AE8584CAA73B); 135 ctx->state[2] = UL64(0x3C6EF372FE94F82B); 136 ctx->state[3] = UL64(0xA54FF53A5F1D36F1); 137 ctx->state[4] = UL64(0x510E527FADE682D1); 138 ctx->state[5] = UL64(0x9B05688C2B3E6C1F); 139 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); 140 ctx->state[7] = UL64(0x5BE0CD19137E2179); 141 } 142 else 143 { 144 /* SHA-384 */ 145 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); 146 ctx->state[1] = UL64(0x629A292A367CD507); 147 ctx->state[2] = UL64(0x9159015A3070DD17); 148 ctx->state[3] = UL64(0x152FECD8F70E5939); 149 ctx->state[4] = UL64(0x67332667FFC00B31); 150 ctx->state[5] = UL64(0x8EB44A8768581511); 151 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); 152 ctx->state[7] = UL64(0x47B5481DBEFA4FA4); 153 } 154 155 ctx->is384 = is384; 156 157 return( 0 ); 158 } 159 160 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 161 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, 162 int is384 ) 163 { 164 mbedtls_sha512_starts_ret( ctx, is384 ); 165 } 166 #endif 167 168 #if !defined(MBEDTLS_SHA512_PROCESS_ALT) 169 170 /* 171 * Round constants 172 */ 173 static const uint64_t K[80] = 174 { 175 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), 176 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), 177 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), 178 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), 179 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), 180 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), 181 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), 182 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), 183 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), 184 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), 185 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), 186 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), 187 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), 188 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), 189 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), 190 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), 191 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), 192 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), 193 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), 194 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), 195 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), 196 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), 197 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), 198 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), 199 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), 200 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), 201 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), 202 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), 203 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), 204 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), 205 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), 206 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), 207 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), 208 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), 209 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), 210 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), 211 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), 212 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), 213 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), 214 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) 215 }; 216 217 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, 218 const unsigned char data[128] ) 219 { 220 int i; 221 uint64_t temp1, temp2, W[80]; 222 uint64_t A, B, C, D, E, F, G, H; 223 224 SHA512_VALIDATE_RET( ctx != NULL ); 225 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL ); 226 227 #define SHR(x,n) (x >> n) 228 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) 229 230 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) 231 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) 232 233 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) 234 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) 235 236 #define F0(x,y,z) ((x & y) | (z & (x | y))) 237 #define F1(x,y,z) (z ^ (x & (y ^ z))) 238 239 #define P(a,b,c,d,e,f,g,h,x,K) \ 240 { \ 241 temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 242 temp2 = S2(a) + F0(a,b,c); \ 243 d += temp1; h = temp1 + temp2; \ 244 } 245 246 for( i = 0; i < 16; i++ ) 247 { 248 GET_UINT64_BE( W[i], data, i << 3 ); 249 } 250 251 for( ; i < 80; i++ ) 252 { 253 W[i] = S1(W[i - 2]) + W[i - 7] + 254 S0(W[i - 15]) + W[i - 16]; 255 } 256 257 A = ctx->state[0]; 258 B = ctx->state[1]; 259 C = ctx->state[2]; 260 D = ctx->state[3]; 261 E = ctx->state[4]; 262 F = ctx->state[5]; 263 G = ctx->state[6]; 264 H = ctx->state[7]; 265 i = 0; 266 267 do 268 { 269 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; 270 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; 271 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; 272 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; 273 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; 274 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; 275 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; 276 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; 277 } 278 while( i < 80 ); 279 280 ctx->state[0] += A; 281 ctx->state[1] += B; 282 ctx->state[2] += C; 283 ctx->state[3] += D; 284 ctx->state[4] += E; 285 ctx->state[5] += F; 286 ctx->state[6] += G; 287 ctx->state[7] += H; 288 289 return( 0 ); 290 } 291 292 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 293 void mbedtls_sha512_process( mbedtls_sha512_context *ctx, 294 const unsigned char data[128] ) 295 { 296 mbedtls_internal_sha512_process( ctx, data ); 297 } 298 #endif 299 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */ 300 301 /* 302 * SHA-512 process buffer 303 */ 304 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, 305 const unsigned char *input, 306 size_t ilen ) 307 { 308 int ret; 309 size_t fill; 310 unsigned int left; 311 312 SHA512_VALIDATE_RET( ctx != NULL ); 313 SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); 314 315 if( ilen == 0 ) 316 return( 0 ); 317 318 left = (unsigned int) (ctx->total[0] & 0x7F); 319 fill = 128 - left; 320 321 ctx->total[0] += (uint64_t) ilen; 322 323 if( ctx->total[0] < (uint64_t) ilen ) 324 ctx->total[1]++; 325 326 if( left && ilen >= fill ) 327 { 328 memcpy( (void *) (ctx->buffer + left), input, fill ); 329 330 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) 331 return( ret ); 332 333 input += fill; 334 ilen -= fill; 335 left = 0; 336 } 337 338 while( ilen >= 128 ) 339 { 340 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) 341 return( ret ); 342 343 input += 128; 344 ilen -= 128; 345 } 346 347 if( ilen > 0 ) 348 memcpy( (void *) (ctx->buffer + left), input, ilen ); 349 350 return( 0 ); 351 } 352 353 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 354 void mbedtls_sha512_update( mbedtls_sha512_context *ctx, 355 const unsigned char *input, 356 size_t ilen ) 357 { 358 mbedtls_sha512_update_ret( ctx, input, ilen ); 359 } 360 #endif 361 362 /* 363 * SHA-512 final digest 364 */ 365 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, 366 unsigned char output[64] ) 367 { 368 int ret; 369 unsigned used; 370 uint64_t high, low; 371 372 SHA512_VALIDATE_RET( ctx != NULL ); 373 SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); 374 375 /* 376 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length 377 */ 378 used = ctx->total[0] & 0x7F; 379 380 ctx->buffer[used++] = 0x80; 381 382 if( used <= 112 ) 383 { 384 /* Enough room for padding + length in current block */ 385 memset( ctx->buffer + used, 0, 112 - used ); 386 } 387 else 388 { 389 /* We'll need an extra block */ 390 memset( ctx->buffer + used, 0, 128 - used ); 391 392 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) 393 return( ret ); 394 395 memset( ctx->buffer, 0, 112 ); 396 } 397 398 /* 399 * Add message length 400 */ 401 high = ( ctx->total[0] >> 61 ) 402 | ( ctx->total[1] << 3 ); 403 low = ( ctx->total[0] << 3 ); 404 405 PUT_UINT64_BE( high, ctx->buffer, 112 ); 406 PUT_UINT64_BE( low, ctx->buffer, 120 ); 407 408 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) 409 return( ret ); 410 411 /* 412 * Output final state 413 */ 414 PUT_UINT64_BE( ctx->state[0], output, 0 ); 415 PUT_UINT64_BE( ctx->state[1], output, 8 ); 416 PUT_UINT64_BE( ctx->state[2], output, 16 ); 417 PUT_UINT64_BE( ctx->state[3], output, 24 ); 418 PUT_UINT64_BE( ctx->state[4], output, 32 ); 419 PUT_UINT64_BE( ctx->state[5], output, 40 ); 420 421 if( ctx->is384 == 0 ) 422 { 423 PUT_UINT64_BE( ctx->state[6], output, 48 ); 424 PUT_UINT64_BE( ctx->state[7], output, 56 ); 425 } 426 427 return( 0 ); 428 } 429 430 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 431 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, 432 unsigned char output[64] ) 433 { 434 mbedtls_sha512_finish_ret( ctx, output ); 435 } 436 #endif 437 438 #endif /* !MBEDTLS_SHA512_ALT */ 439 440 /* 441 * output = SHA-512( input buffer ) 442 */ 443 int mbedtls_sha512_ret( const unsigned char *input, 444 size_t ilen, 445 unsigned char output[64], 446 int is384 ) 447 { 448 int ret; 449 mbedtls_sha512_context ctx; 450 451 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); 452 SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); 453 SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); 454 455 mbedtls_sha512_init( &ctx ); 456 457 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 ) 458 goto exit; 459 460 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 ) 461 goto exit; 462 463 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 ) 464 goto exit; 465 466 exit: 467 mbedtls_sha512_free( &ctx ); 468 469 return( ret ); 470 } 471 472 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 473 void mbedtls_sha512( const unsigned char *input, 474 size_t ilen, 475 unsigned char output[64], 476 int is384 ) 477 { 478 mbedtls_sha512_ret( input, ilen, output, is384 ); 479 } 480 #endif 481 482 #if defined(MBEDTLS_SELF_TEST) 483 484 /* 485 * FIPS-180-2 test vectors 486 */ 487 static const unsigned char sha512_test_buf[3][113] = 488 { 489 { "abc" }, 490 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" 491 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, 492 { "" } 493 }; 494 495 static const size_t sha512_test_buflen[3] = 496 { 497 3, 112, 1000 498 }; 499 500 static const unsigned char sha512_test_sum[6][64] = 501 { 502 /* 503 * SHA-384 test vectors 504 */ 505 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, 506 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, 507 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, 508 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, 509 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, 510 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, 511 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, 512 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, 513 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, 514 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, 515 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, 516 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, 517 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, 518 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, 519 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, 520 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, 521 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, 522 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, 523 524 /* 525 * SHA-512 test vectors 526 */ 527 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, 528 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, 529 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, 530 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, 531 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, 532 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, 533 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, 534 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, 535 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, 536 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, 537 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, 538 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, 539 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, 540 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, 541 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, 542 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, 543 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, 544 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, 545 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, 546 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, 547 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, 548 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, 549 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, 550 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } 551 }; 552 553 /* 554 * Checkup routine 555 */ 556 int mbedtls_sha512_self_test( int verbose ) 557 { 558 int i, j, k, buflen, ret = 0; 559 unsigned char *buf; 560 unsigned char sha512sum[64]; 561 mbedtls_sha512_context ctx; 562 563 buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); 564 if( NULL == buf ) 565 { 566 if( verbose != 0 ) 567 mbedtls_printf( "Buffer allocation failed\n" ); 568 569 return( 1 ); 570 } 571 572 mbedtls_sha512_init( &ctx ); 573 574 for( i = 0; i < 6; i++ ) 575 { 576 j = i % 3; 577 k = i < 3; 578 579 if( verbose != 0 ) 580 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); 581 582 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 ) 583 goto fail; 584 585 if( j == 2 ) 586 { 587 memset( buf, 'a', buflen = 1000 ); 588 589 for( j = 0; j < 1000; j++ ) 590 { 591 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen ); 592 if( ret != 0 ) 593 goto fail; 594 } 595 } 596 else 597 { 598 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j], 599 sha512_test_buflen[j] ); 600 if( ret != 0 ) 601 goto fail; 602 } 603 604 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 ) 605 goto fail; 606 607 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) 608 { 609 ret = 1; 610 goto fail; 611 } 612 613 if( verbose != 0 ) 614 mbedtls_printf( "passed\n" ); 615 } 616 617 if( verbose != 0 ) 618 mbedtls_printf( "\n" ); 619 620 goto exit; 621 622 fail: 623 if( verbose != 0 ) 624 mbedtls_printf( "failed\n" ); 625 626 exit: 627 mbedtls_sha512_free( &ctx ); 628 mbedtls_free( buf ); 629 630 return( ret ); 631 } 632 633 #endif /* MBEDTLS_SELF_TEST */ 634 635 #endif /* MBEDTLS_SHA512_C */ 636