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