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