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