LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - sha512.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 63.5 % 189 120
Test Date: 2025-06-29 08:09:00 Functions: 66.7 % 12 8

            Line data    Source code
       1              : /*
       2              :  *  FIPS-180-2 compliant SHA-384/512 implementation
       3              :  *
       4              :  *  Copyright The Mbed TLS Contributors
       5              :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       6              :  */
       7              : /*
       8              :  *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
       9              :  *
      10              :  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
      11              :  */
      12              : 
      13              : #if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
      14              :     defined(__clang__) && __clang_major__ >= 7
      15              : /* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
      16              :  *
      17              :  * The intrinsic declaration are guarded by predefined ACLE macros in clang:
      18              :  * these are normally only enabled by the -march option on the command line.
      19              :  * By defining the macros ourselves we gain access to those declarations without
      20              :  * requiring -march on the command line.
      21              :  *
      22              :  * `arm_neon.h` is included by common.h, so we put these defines
      23              :  * at the top of this file, before any includes.
      24              :  */
      25              : #define __ARM_FEATURE_SHA512 1
      26              : #define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG
      27              : #endif
      28              : 
      29              : #include "common.h"
      30              : 
      31              : #if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
      32              : 
      33              : #include "mbedtls/sha512.h"
      34              : #include "mbedtls/platform_util.h"
      35              : #include "mbedtls/error.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              : #include "mbedtls/platform.h"
      46              : 
      47              : #if defined(__aarch64__)
      48              : #  if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
      49              :     defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
      50              : /* *INDENT-OFF* */
      51              : #   if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
      52              : #       error "Target does not support NEON instructions"
      53              : #   endif
      54              : /*
      55              :  * Best performance comes from most recent compilers, with intrinsics and -O3.
      56              :  * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
      57              :  * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
      58              :  *
      59              :  * GCC < 8 won't work at all (lacks the sha512 instructions)
      60              :  * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
      61              :  *
      62              :  * Clang < 7 won't work at all (lacks the sha512 instructions)
      63              :  * Clang 7-12 don't have intrinsics (but we work around that with inline
      64              :  *            assembler) or __ARM_FEATURE_SHA512
      65              :  * Clang == 13.0.0 same as clang 12 (only seen on macOS)
      66              :  * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
      67              :  */
      68              : #    if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
      69              :        /* Test Clang first, as it defines __GNUC__ */
      70              : #      if defined(__ARMCOMPILER_VERSION)
      71              : #        if __ARMCOMPILER_VERSION < 6090000
      72              : #          error "A more recent armclang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
      73              : #        elif __ARMCOMPILER_VERSION == 6090000
      74              : #          error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
      75              : #        else
      76              : #          pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
      77              : #          define MBEDTLS_POP_TARGET_PRAGMA
      78              : #        endif
      79              : #      elif defined(__clang__)
      80              : #        if __clang_major__ < 7
      81              : #          error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
      82              : #        else
      83              : #          pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
      84              : #          define MBEDTLS_POP_TARGET_PRAGMA
      85              : #        endif
      86              : #      elif defined(__GNUC__)
      87              : #        if __GNUC__ < 8
      88              : #          error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
      89              : #        else
      90              : #          pragma GCC push_options
      91              : #          pragma GCC target ("arch=armv8.2-a+sha3")
      92              : #          define MBEDTLS_POP_TARGET_PRAGMA
      93              : #        endif
      94              : #      else
      95              : #        error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
      96              : #      endif
      97              : #    endif
      98              : /* *INDENT-ON* */
      99              : #  endif
     100              : #  if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
     101              : #    if defined(__unix__)
     102              : #      if defined(__linux__)
     103              : /* Our preferred method of detection is getauxval() */
     104              : #        include <sys/auxv.h>
     105              : #        if !defined(HWCAP_SHA512)
     106              : /* The same header that declares getauxval() should provide the HWCAP_xxx
     107              :  * constants to analyze its return value. However, the libc may be too
     108              :  * old to have the constant that we need. So if it's missing, assume that
     109              :  * the value is the same one used by the Linux kernel ABI.
     110              :  */
     111              : #          define HWCAP_SHA512 (1 << 21)
     112              : #        endif
     113              : #      endif
     114              : /* Use SIGILL on Unix, and fall back to it on Linux */
     115              : #      include <signal.h>
     116              : #    endif
     117              : #  endif
     118              : #elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
     119              : #  undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
     120              : #  undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
     121              : #endif
     122              : 
     123              : #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
     124              : /*
     125              :  * Capability detection code comes early, so we can disable
     126              :  * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
     127              :  */
     128              : #if defined(HWCAP_SHA512)
     129              : static int mbedtls_a64_crypto_sha512_determine_support(void)
     130              : {
     131              :     return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
     132              : }
     133              : #elif defined(__APPLE__)
     134              : #include <sys/types.h>
     135              : #include <sys/sysctl.h>
     136              : 
     137              : static int mbedtls_a64_crypto_sha512_determine_support(void)
     138              : {
     139              :     int value = 0;
     140              :     size_t value_len = sizeof(value);
     141              : 
     142              :     int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
     143              :                            NULL, 0);
     144              :     return ret == 0 && value != 0;
     145              : }
     146              : #elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
     147              : /*
     148              :  * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
     149              :  * available to pass to IsProcessorFeaturePresent() to check for
     150              :  * SHA-512 support. So we fall back to the C code only.
     151              :  */
     152              : #if defined(_MSC_VER)
     153              : #pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
     154              : #else
     155              : #warning "No mechanism to detect A64_CRYPTO found, using C code only"
     156              : #endif
     157              : #elif defined(__unix__) && defined(SIG_SETMASK)
     158              : /* Detection with SIGILL, setjmp() and longjmp() */
     159              : #include <signal.h>
     160              : #include <setjmp.h>
     161              : 
     162              : static jmp_buf return_from_sigill;
     163              : 
     164              : /*
     165              :  * A64 SHA512 support detection via SIGILL
     166              :  */
     167              : static void sigill_handler(int signal)
     168              : {
     169              :     (void) signal;
     170              :     longjmp(return_from_sigill, 1);
     171              : }
     172              : 
     173              : static int mbedtls_a64_crypto_sha512_determine_support(void)
     174              : {
     175              :     struct sigaction old_action, new_action;
     176              : 
     177              :     sigset_t old_mask;
     178              :     if (sigprocmask(0, NULL, &old_mask)) {
     179              :         return 0;
     180              :     }
     181              : 
     182              :     sigemptyset(&new_action.sa_mask);
     183              :     new_action.sa_flags = 0;
     184              :     new_action.sa_handler = sigill_handler;
     185              : 
     186              :     sigaction(SIGILL, &new_action, &old_action);
     187              : 
     188              :     static int ret = 0;
     189              : 
     190              :     if (setjmp(return_from_sigill) == 0) {         /* First return only */
     191              :         /* If this traps, we will return a second time from setjmp() with 1 */
     192              :         asm ("sha512h q0, q0, v0.2d" : : : "v0");
     193              :         ret = 1;
     194              :     }
     195              : 
     196              :     sigaction(SIGILL, &old_action, NULL);
     197              :     sigprocmask(SIG_SETMASK, &old_mask, NULL);
     198              : 
     199              :     return ret;
     200              : }
     201              : #else
     202              : #warning "No mechanism to detect A64_CRYPTO found, using C code only"
     203              : #undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
     204              : #endif  /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
     205              : 
     206              : #endif  /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
     207              : 
     208              : #if !defined(MBEDTLS_SHA512_ALT)
     209              : 
     210              : #define SHA512_BLOCK_SIZE 128
     211              : 
     212              : #if defined(MBEDTLS_SHA512_SMALLER)
     213              : static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
     214              : {
     215              :     MBEDTLS_PUT_UINT64_BE(n, b, i);
     216              : }
     217              : #else
     218              : #define sha512_put_uint64_be    MBEDTLS_PUT_UINT64_BE
     219              : #endif /* MBEDTLS_SHA512_SMALLER */
     220              : 
     221          261 : void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
     222              : {
     223          261 :     memset(ctx, 0, sizeof(mbedtls_sha512_context));
     224          261 : }
     225              : 
     226          524 : void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
     227              : {
     228          524 :     if (ctx == NULL) {
     229            0 :         return;
     230              :     }
     231              : 
     232          524 :     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
     233              : }
     234              : 
     235            0 : void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
     236              :                           const mbedtls_sha512_context *src)
     237              : {
     238            0 :     *dst = *src;
     239            0 : }
     240              : 
     241              : /*
     242              :  * SHA-512 context setup
     243              :  */
     244          263 : int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
     245              : {
     246              : #if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
     247          263 :     if (is384 != 0 && is384 != 1) {
     248            0 :         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
     249              :     }
     250              : #elif defined(MBEDTLS_SHA512_C)
     251              :     if (is384 != 0) {
     252              :         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
     253              :     }
     254              : #else /* defined MBEDTLS_SHA384_C only */
     255              :     if (is384 == 0) {
     256              :         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
     257              :     }
     258              : #endif
     259              : 
     260          263 :     ctx->total[0] = 0;
     261          263 :     ctx->total[1] = 0;
     262              : 
     263          263 :     if (is384 == 0) {
     264              : #if defined(MBEDTLS_SHA512_C)
     265           46 :         ctx->state[0] = UL64(0x6A09E667F3BCC908);
     266           46 :         ctx->state[1] = UL64(0xBB67AE8584CAA73B);
     267           46 :         ctx->state[2] = UL64(0x3C6EF372FE94F82B);
     268           46 :         ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
     269           46 :         ctx->state[4] = UL64(0x510E527FADE682D1);
     270           46 :         ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
     271           46 :         ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
     272           46 :         ctx->state[7] = UL64(0x5BE0CD19137E2179);
     273              : #endif /* MBEDTLS_SHA512_C */
     274              :     } else {
     275              : #if defined(MBEDTLS_SHA384_C)
     276          217 :         ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
     277          217 :         ctx->state[1] = UL64(0x629A292A367CD507);
     278          217 :         ctx->state[2] = UL64(0x9159015A3070DD17);
     279          217 :         ctx->state[3] = UL64(0x152FECD8F70E5939);
     280          217 :         ctx->state[4] = UL64(0x67332667FFC00B31);
     281          217 :         ctx->state[5] = UL64(0x8EB44A8768581511);
     282          217 :         ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
     283          217 :         ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
     284              : #endif /* MBEDTLS_SHA384_C */
     285              :     }
     286              : 
     287              : #if defined(MBEDTLS_SHA384_C)
     288          263 :     ctx->is384 = is384;
     289              : #endif
     290              : 
     291          263 :     return 0;
     292              : }
     293              : 
     294              : #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
     295              : 
     296              : /*
     297              :  * Round constants
     298              :  */
     299              : static const uint64_t K[80] =
     300              : {
     301              :     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
     302              :     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
     303              :     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
     304              :     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
     305              :     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
     306              :     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
     307              :     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
     308              :     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
     309              :     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
     310              :     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
     311              :     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
     312              :     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
     313              :     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
     314              :     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
     315              :     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
     316              :     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
     317              :     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
     318              :     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
     319              :     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
     320              :     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
     321              :     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
     322              :     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
     323              :     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
     324              :     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
     325              :     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
     326              :     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
     327              :     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
     328              :     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
     329              :     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
     330              :     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
     331              :     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
     332              :     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
     333              :     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
     334              :     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
     335              :     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
     336              :     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
     337              :     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
     338              :     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
     339              :     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
     340              :     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
     341              : };
     342              : #endif
     343              : 
     344              : #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
     345              :     defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
     346              : 
     347              : #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
     348              : #  define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
     349              : #  define mbedtls_internal_sha512_process_a64_crypto      mbedtls_internal_sha512_process
     350              : #endif
     351              : 
     352              : /* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
     353              :  * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
     354              :  */
     355              : 
     356              : #if defined(__clang__) && \
     357              :     (__clang_major__ < 13 || \
     358              :      (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
     359              : static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
     360              : {
     361              :     asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
     362              :     return x;
     363              : }
     364              : static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
     365              : {
     366              :     asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
     367              :     return x;
     368              : }
     369              : static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
     370              : {
     371              :     asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
     372              :     return x;
     373              : }
     374              : static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
     375              : {
     376              :     asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
     377              :     return x;
     378              : }
     379              : #endif  /* __clang__ etc */
     380              : 
     381              : static size_t mbedtls_internal_sha512_process_many_a64_crypto(
     382              :     mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
     383              : {
     384              :     uint64x2_t ab = vld1q_u64(&ctx->state[0]);
     385              :     uint64x2_t cd = vld1q_u64(&ctx->state[2]);
     386              :     uint64x2_t ef = vld1q_u64(&ctx->state[4]);
     387              :     uint64x2_t gh = vld1q_u64(&ctx->state[6]);
     388              : 
     389              :     size_t processed = 0;
     390              : 
     391              :     for (;
     392              :          len >= SHA512_BLOCK_SIZE;
     393              :          processed += SHA512_BLOCK_SIZE,
     394              :          msg += SHA512_BLOCK_SIZE,
     395              :          len -= SHA512_BLOCK_SIZE) {
     396              :         uint64x2_t initial_sum, sum, intermed;
     397              : 
     398              :         uint64x2_t ab_orig = ab;
     399              :         uint64x2_t cd_orig = cd;
     400              :         uint64x2_t ef_orig = ef;
     401              :         uint64x2_t gh_orig = gh;
     402              : 
     403              :         uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
     404              :         uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
     405              :         uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
     406              :         uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
     407              :         uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
     408              :         uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
     409              :         uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
     410              :         uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
     411              : 
     412              : #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__  /* assume LE if these not defined; untested on BE */
     413              :         s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
     414              :         s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
     415              :         s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
     416              :         s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
     417              :         s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
     418              :         s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
     419              :         s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
     420              :         s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
     421              : #endif
     422              : 
     423              :         /* Rounds 0 and 1 */
     424              :         initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
     425              :         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
     426              :         intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
     427              :         gh = vsha512h2q_u64(intermed, cd, ab);
     428              :         cd = vaddq_u64(cd, intermed);
     429              : 
     430              :         /* Rounds 2 and 3 */
     431              :         initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
     432              :         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
     433              :         intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
     434              :         ef = vsha512h2q_u64(intermed, ab, gh);
     435              :         ab = vaddq_u64(ab, intermed);
     436              : 
     437              :         /* Rounds 4 and 5 */
     438              :         initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
     439              :         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
     440              :         intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
     441              :         cd = vsha512h2q_u64(intermed, gh, ef);
     442              :         gh = vaddq_u64(gh, intermed);
     443              : 
     444              :         /* Rounds 6 and 7 */
     445              :         initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
     446              :         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
     447              :         intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
     448              :         ab = vsha512h2q_u64(intermed, ef, cd);
     449              :         ef = vaddq_u64(ef, intermed);
     450              : 
     451              :         /* Rounds 8 and 9 */
     452              :         initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
     453              :         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
     454              :         intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
     455              :         gh = vsha512h2q_u64(intermed, cd, ab);
     456              :         cd = vaddq_u64(cd, intermed);
     457              : 
     458              :         /* Rounds 10 and 11 */
     459              :         initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
     460              :         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
     461              :         intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
     462              :         ef = vsha512h2q_u64(intermed, ab, gh);
     463              :         ab = vaddq_u64(ab, intermed);
     464              : 
     465              :         /* Rounds 12 and 13 */
     466              :         initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
     467              :         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
     468              :         intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
     469              :         cd = vsha512h2q_u64(intermed, gh, ef);
     470              :         gh = vaddq_u64(gh, intermed);
     471              : 
     472              :         /* Rounds 14 and 15 */
     473              :         initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
     474              :         sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
     475              :         intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
     476              :         ab = vsha512h2q_u64(intermed, ef, cd);
     477              :         ef = vaddq_u64(ef, intermed);
     478              : 
     479              :         for (unsigned int t = 16; t < 80; t += 16) {
     480              :             /* Rounds t and t + 1 */
     481              :             s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
     482              :             initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
     483              :             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
     484              :             intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
     485              :             gh = vsha512h2q_u64(intermed, cd, ab);
     486              :             cd = vaddq_u64(cd, intermed);
     487              : 
     488              :             /* Rounds t + 2 and t + 3 */
     489              :             s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
     490              :             initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
     491              :             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
     492              :             intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
     493              :             ef = vsha512h2q_u64(intermed, ab, gh);
     494              :             ab = vaddq_u64(ab, intermed);
     495              : 
     496              :             /* Rounds t + 4 and t + 5 */
     497              :             s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
     498              :             initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
     499              :             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
     500              :             intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
     501              :             cd = vsha512h2q_u64(intermed, gh, ef);
     502              :             gh = vaddq_u64(gh, intermed);
     503              : 
     504              :             /* Rounds t + 6 and t + 7 */
     505              :             s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
     506              :             initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
     507              :             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
     508              :             intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
     509              :             ab = vsha512h2q_u64(intermed, ef, cd);
     510              :             ef = vaddq_u64(ef, intermed);
     511              : 
     512              :             /* Rounds t + 8 and t + 9 */
     513              :             s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
     514              :             initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
     515              :             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
     516              :             intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
     517              :             gh = vsha512h2q_u64(intermed, cd, ab);
     518              :             cd = vaddq_u64(cd, intermed);
     519              : 
     520              :             /* Rounds t + 10 and t + 11 */
     521              :             s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
     522              :             initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
     523              :             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
     524              :             intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
     525              :             ef = vsha512h2q_u64(intermed, ab, gh);
     526              :             ab = vaddq_u64(ab, intermed);
     527              : 
     528              :             /* Rounds t + 12 and t + 13 */
     529              :             s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
     530              :             initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
     531              :             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
     532              :             intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
     533              :             cd = vsha512h2q_u64(intermed, gh, ef);
     534              :             gh = vaddq_u64(gh, intermed);
     535              : 
     536              :             /* Rounds t + 14 and t + 15 */
     537              :             s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
     538              :             initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
     539              :             sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
     540              :             intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
     541              :             ab = vsha512h2q_u64(intermed, ef, cd);
     542              :             ef = vaddq_u64(ef, intermed);
     543              :         }
     544              : 
     545              :         ab = vaddq_u64(ab, ab_orig);
     546              :         cd = vaddq_u64(cd, cd_orig);
     547              :         ef = vaddq_u64(ef, ef_orig);
     548              :         gh = vaddq_u64(gh, gh_orig);
     549              :     }
     550              : 
     551              :     vst1q_u64(&ctx->state[0], ab);
     552              :     vst1q_u64(&ctx->state[2], cd);
     553              :     vst1q_u64(&ctx->state[4], ef);
     554              :     vst1q_u64(&ctx->state[6], gh);
     555              : 
     556              :     return processed;
     557              : }
     558              : 
     559              : #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
     560              : /*
     561              :  * This function is for internal use only if we are building both C and A64
     562              :  * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
     563              :  */
     564              : static
     565              : #endif
     566              : int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
     567              :                                                const unsigned char data[SHA512_BLOCK_SIZE])
     568              : {
     569              :     return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
     570              :                                                             SHA512_BLOCK_SIZE) ==
     571              :             SHA512_BLOCK_SIZE) ? 0 : -1;
     572              : }
     573              : 
     574              : #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
     575              : 
     576              : #if defined(MBEDTLS_POP_TARGET_PRAGMA)
     577              : #if defined(__clang__)
     578              : #pragma clang attribute pop
     579              : #elif defined(__GNUC__)
     580              : #pragma GCC pop_options
     581              : #endif
     582              : #undef MBEDTLS_POP_TARGET_PRAGMA
     583              : #endif
     584              : 
     585              : 
     586              : #if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
     587              : #define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
     588              : #define mbedtls_internal_sha512_process_c      mbedtls_internal_sha512_process
     589              : #endif
     590              : 
     591              : 
     592              : #if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
     593              : 
     594              : #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
     595              : /*
     596              :  * This function is for internal use only if we are building both C and A64
     597              :  * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
     598              :  */
     599              : static
     600              : #endif
     601          536 : int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
     602              :                                       const unsigned char data[SHA512_BLOCK_SIZE])
     603              : {
     604              :     int i;
     605              :     struct {
     606              :         uint64_t temp1, temp2, W[80];
     607              :         uint64_t A[8];
     608              :     } local;
     609              : 
     610              : #define  SHR(x, n) ((x) >> (n))
     611              : #define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
     612              : 
     613              : #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
     614              : #define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^  SHR(x, 6))
     615              : 
     616              : #define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
     617              : #define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
     618              : 
     619              : #define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
     620              : #define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
     621              : 
     622              : #define P(a, b, c, d, e, f, g, h, x, K)                                      \
     623              :     do                                                              \
     624              :     {                                                               \
     625              :         local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x);    \
     626              :         local.temp2 = S2(a) + F0((a), (b), (c));                      \
     627              :         (d) += local.temp1; (h) = local.temp1 + local.temp2;        \
     628              :     } while (0)
     629              : 
     630         4824 :     for (i = 0; i < 8; i++) {
     631         4288 :         local.A[i] = ctx->state[i];
     632              :     }
     633              : 
     634              : #if defined(MBEDTLS_SHA512_SMALLER)
     635              :     for (i = 0; i < 80; i++) {
     636              :         if (i < 16) {
     637              :             local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
     638              :         } else {
     639              :             local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
     640              :                          S0(local.W[i - 15]) + local.W[i - 16];
     641              :         }
     642              : 
     643              :         P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
     644              :           local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
     645              : 
     646              :         local.temp1 = local.A[7]; local.A[7] = local.A[6];
     647              :         local.A[6] = local.A[5]; local.A[5] = local.A[4];
     648              :         local.A[4] = local.A[3]; local.A[3] = local.A[2];
     649              :         local.A[2] = local.A[1]; local.A[1] = local.A[0];
     650              :         local.A[0] = local.temp1;
     651              :     }
     652              : #else /* MBEDTLS_SHA512_SMALLER */
     653         9112 :     for (i = 0; i < 16; i++) {
     654        17152 :         local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
     655              :     }
     656              : 
     657        34840 :     for (; i < 80; i++) {
     658        34304 :         local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
     659        34304 :                      S0(local.W[i - 15]) + local.W[i - 16];
     660              :     }
     661              : 
     662          536 :     i = 0;
     663              :     do {
     664         5360 :         P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
     665         5360 :           local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
     666         5360 :         P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
     667         5360 :           local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
     668         5360 :         P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
     669         5360 :           local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
     670         5360 :         P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
     671         5360 :           local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
     672         5360 :         P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
     673         5360 :           local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
     674         5360 :         P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
     675         5360 :           local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
     676         5360 :         P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
     677         5360 :           local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
     678         5360 :         P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
     679         5360 :           local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
     680         5360 :     } while (i < 80);
     681              : #endif /* MBEDTLS_SHA512_SMALLER */
     682              : 
     683         4824 :     for (i = 0; i < 8; i++) {
     684         4288 :         ctx->state[i] += local.A[i];
     685              :     }
     686              : 
     687              :     /* Zeroise buffers and variables to clear sensitive data from memory. */
     688          536 :     mbedtls_platform_zeroize(&local, sizeof(local));
     689              : 
     690          536 :     return 0;
     691              : }
     692              : 
     693              : #endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
     694              : 
     695              : 
     696              : #if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
     697              : 
     698           49 : static size_t mbedtls_internal_sha512_process_many_c(
     699              :     mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
     700              : {
     701           49 :     size_t processed = 0;
     702              : 
     703          322 :     while (len >= SHA512_BLOCK_SIZE) {
     704          273 :         if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
     705            0 :             return 0;
     706              :         }
     707              : 
     708          273 :         data += SHA512_BLOCK_SIZE;
     709          273 :         len  -= SHA512_BLOCK_SIZE;
     710              : 
     711          273 :         processed += SHA512_BLOCK_SIZE;
     712              :     }
     713              : 
     714           49 :     return processed;
     715              : }
     716              : 
     717              : #endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
     718              : 
     719              : 
     720              : #if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
     721              : 
     722              : static int mbedtls_a64_crypto_sha512_has_support(void)
     723              : {
     724              :     static int done = 0;
     725              :     static int supported = 0;
     726              : 
     727              :     if (!done) {
     728              :         supported = mbedtls_a64_crypto_sha512_determine_support();
     729              :         done = 1;
     730              :     }
     731              : 
     732              :     return supported;
     733              : }
     734              : 
     735              : static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
     736              :                                                    const uint8_t *msg, size_t len)
     737              : {
     738              :     if (mbedtls_a64_crypto_sha512_has_support()) {
     739              :         return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
     740              :     } else {
     741              :         return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
     742              :     }
     743              : }
     744              : 
     745              : int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
     746              :                                     const unsigned char data[SHA512_BLOCK_SIZE])
     747              : {
     748              :     if (mbedtls_a64_crypto_sha512_has_support()) {
     749              :         return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
     750              :     } else {
     751              :         return mbedtls_internal_sha512_process_c(ctx, data);
     752              :     }
     753              : }
     754              : 
     755              : #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
     756              : 
     757              : /*
     758              :  * SHA-512 process buffer
     759              :  */
     760          267 : int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
     761              :                           const unsigned char *input,
     762              :                           size_t ilen)
     763              : {
     764          267 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     765              :     size_t fill;
     766              :     unsigned int left;
     767              : 
     768          267 :     if (ilen == 0) {
     769            0 :         return 0;
     770              :     }
     771              : 
     772          267 :     left = (unsigned int) (ctx->total[0] & 0x7F);
     773          267 :     fill = SHA512_BLOCK_SIZE - left;
     774              : 
     775          267 :     ctx->total[0] += (uint64_t) ilen;
     776              : 
     777          267 :     if (ctx->total[0] < (uint64_t) ilen) {
     778            0 :         ctx->total[1]++;
     779              :     }
     780              : 
     781          267 :     if (left && ilen >= fill) {
     782            0 :         memcpy((void *) (ctx->buffer + left), input, fill);
     783              : 
     784            0 :         if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
     785            0 :             return ret;
     786              :         }
     787              : 
     788            0 :         input += fill;
     789            0 :         ilen  -= fill;
     790            0 :         left = 0;
     791              :     }
     792              : 
     793          316 :     while (ilen >= SHA512_BLOCK_SIZE) {
     794              :         size_t processed =
     795           49 :             mbedtls_internal_sha512_process_many(ctx, input, ilen);
     796           49 :         if (processed < SHA512_BLOCK_SIZE) {
     797            0 :             return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
     798              :         }
     799              : 
     800           49 :         input += processed;
     801           49 :         ilen  -= processed;
     802              :     }
     803              : 
     804          267 :     if (ilen > 0) {
     805          263 :         memcpy((void *) (ctx->buffer + left), input, ilen);
     806              :     }
     807              : 
     808          267 :     return 0;
     809              : }
     810              : 
     811              : /*
     812              :  * SHA-512 final digest
     813              :  */
     814          263 : int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
     815              :                           unsigned char *output)
     816              : {
     817          263 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     818              :     unsigned used;
     819              :     uint64_t high, low;
     820          263 :     int truncated = 0;
     821              : 
     822              :     /*
     823              :      * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
     824              :      */
     825          263 :     used = ctx->total[0] & 0x7F;
     826              : 
     827          263 :     ctx->buffer[used++] = 0x80;
     828              : 
     829          263 :     if (used <= 112) {
     830              :         /* Enough room for padding + length in current block */
     831          263 :         memset(ctx->buffer + used, 0, 112 - used);
     832              :     } else {
     833              :         /* We'll need an extra block */
     834            0 :         memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
     835              : 
     836            0 :         if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
     837            0 :             goto exit;
     838              :         }
     839              : 
     840            0 :         memset(ctx->buffer, 0, 112);
     841              :     }
     842              : 
     843              :     /*
     844              :      * Add message length
     845              :      */
     846          263 :     high = (ctx->total[0] >> 61)
     847          263 :            | (ctx->total[1] <<  3);
     848          263 :     low  = (ctx->total[0] <<  3);
     849              : 
     850          263 :     sha512_put_uint64_be(high, ctx->buffer, 112);
     851          263 :     sha512_put_uint64_be(low,  ctx->buffer, 120);
     852              : 
     853          263 :     if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
     854            0 :         goto exit;
     855              :     }
     856              : 
     857              :     /*
     858              :      * Output final state
     859              :      */
     860          263 :     sha512_put_uint64_be(ctx->state[0], output,  0);
     861          263 :     sha512_put_uint64_be(ctx->state[1], output,  8);
     862          263 :     sha512_put_uint64_be(ctx->state[2], output, 16);
     863          263 :     sha512_put_uint64_be(ctx->state[3], output, 24);
     864          263 :     sha512_put_uint64_be(ctx->state[4], output, 32);
     865          263 :     sha512_put_uint64_be(ctx->state[5], output, 40);
     866              : 
     867              : #if defined(MBEDTLS_SHA384_C)
     868          263 :     truncated = ctx->is384;
     869              : #endif
     870          263 :     if (!truncated) {
     871           46 :         sha512_put_uint64_be(ctx->state[6], output, 48);
     872           46 :         sha512_put_uint64_be(ctx->state[7], output, 56);
     873              :     }
     874              : 
     875          263 :     ret = 0;
     876              : 
     877          263 : exit:
     878          263 :     mbedtls_sha512_free(ctx);
     879          263 :     return ret;
     880              : }
     881              : 
     882              : #endif /* !MBEDTLS_SHA512_ALT */
     883              : 
     884              : /*
     885              :  * output = SHA-512( input buffer )
     886              :  */
     887          259 : int mbedtls_sha512(const unsigned char *input,
     888              :                    size_t ilen,
     889              :                    unsigned char *output,
     890              :                    int is384)
     891              : {
     892          259 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     893              :     mbedtls_sha512_context ctx;
     894              : 
     895              : #if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
     896          259 :     if (is384 != 0 && is384 != 1) {
     897            0 :         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
     898              :     }
     899              : #elif defined(MBEDTLS_SHA512_C)
     900              :     if (is384 != 0) {
     901              :         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
     902              :     }
     903              : #else /* defined MBEDTLS_SHA384_C only */
     904              :     if (is384 == 0) {
     905              :         return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
     906              :     }
     907              : #endif
     908              : 
     909          259 :     mbedtls_sha512_init(&ctx);
     910              : 
     911          259 :     if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
     912            0 :         goto exit;
     913              :     }
     914              : 
     915          259 :     if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
     916            0 :         goto exit;
     917              :     }
     918              : 
     919          259 :     if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
     920            0 :         goto exit;
     921              :     }
     922              : 
     923          259 : exit:
     924          259 :     mbedtls_sha512_free(&ctx);
     925              : 
     926          259 :     return ret;
     927              : }
     928              : 
     929              : #if defined(MBEDTLS_SELF_TEST)
     930              : 
     931              : /*
     932              :  * FIPS-180-2 test vectors
     933              :  */
     934              : static const unsigned char sha_test_buf[3][113] =
     935              : {
     936              :     { "abc" },
     937              :     {
     938              :         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
     939              :     },
     940              :     { "" }
     941              : };
     942              : 
     943              : static const size_t sha_test_buflen[3] =
     944              : {
     945              :     3, 112, 1000
     946              : };
     947              : 
     948              : typedef const unsigned char (sha_test_sum_t)[64];
     949              : 
     950              : /*
     951              :  * SHA-384 test vectors
     952              :  */
     953              : #if defined(MBEDTLS_SHA384_C)
     954              : static sha_test_sum_t sha384_test_sum[] =
     955              : {
     956              :     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
     957              :       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
     958              :       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
     959              :       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
     960              :       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
     961              :       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
     962              :     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
     963              :       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
     964              :       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
     965              :       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
     966              :       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
     967              :       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
     968              :     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
     969              :       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
     970              :       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
     971              :       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
     972              :       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
     973              :       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
     974              : };
     975              : #endif /* MBEDTLS_SHA384_C */
     976              : 
     977              : /*
     978              :  * SHA-512 test vectors
     979              :  */
     980              : #if defined(MBEDTLS_SHA512_C)
     981              : static sha_test_sum_t sha512_test_sum[] =
     982              : {
     983              :     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
     984              :       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
     985              :       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
     986              :       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
     987              :       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
     988              :       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
     989              :       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
     990              :       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
     991              :     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
     992              :       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
     993              :       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
     994              :       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
     995              :       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
     996              :       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
     997              :       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
     998              :       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
     999              :     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
    1000              :       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
    1001              :       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
    1002              :       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
    1003              :       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
    1004              :       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
    1005              :       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
    1006              :       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
    1007              : };
    1008              : #endif /* MBEDTLS_SHA512_C */
    1009              : 
    1010            0 : static int mbedtls_sha512_common_self_test(int verbose, int is384)
    1011              : {
    1012            0 :     int i, buflen, ret = 0;
    1013              :     unsigned char *buf;
    1014              :     unsigned char sha512sum[64];
    1015              :     mbedtls_sha512_context ctx;
    1016              : 
    1017              : #if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
    1018            0 :     sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
    1019              : #elif defined(MBEDTLS_SHA512_C)
    1020              :     sha_test_sum_t *sha_test_sum = sha512_test_sum;
    1021              : #else
    1022              :     sha_test_sum_t *sha_test_sum = sha384_test_sum;
    1023              : #endif
    1024              : 
    1025            0 :     buf = mbedtls_calloc(1024, sizeof(unsigned char));
    1026            0 :     if (NULL == buf) {
    1027            0 :         if (verbose != 0) {
    1028            0 :             mbedtls_printf("Buffer allocation failed\n");
    1029              :         }
    1030              : 
    1031            0 :         return 1;
    1032              :     }
    1033              : 
    1034            0 :     mbedtls_sha512_init(&ctx);
    1035              : 
    1036            0 :     for (i = 0; i < 3; i++) {
    1037            0 :         if (verbose != 0) {
    1038            0 :             mbedtls_printf("  SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
    1039              :         }
    1040              : 
    1041            0 :         if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
    1042            0 :             goto fail;
    1043              :         }
    1044              : 
    1045            0 :         if (i == 2) {
    1046            0 :             memset(buf, 'a', buflen = 1000);
    1047              : 
    1048            0 :             for (int j = 0; j < 1000; j++) {
    1049            0 :                 ret = mbedtls_sha512_update(&ctx, buf, buflen);
    1050            0 :                 if (ret != 0) {
    1051            0 :                     goto fail;
    1052              :                 }
    1053              :             }
    1054              :         } else {
    1055            0 :             ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
    1056            0 :                                         sha_test_buflen[i]);
    1057            0 :             if (ret != 0) {
    1058            0 :                 goto fail;
    1059              :             }
    1060              :         }
    1061              : 
    1062            0 :         if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
    1063            0 :             goto fail;
    1064              :         }
    1065              : 
    1066            0 :         if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
    1067            0 :             ret = 1;
    1068            0 :             goto fail;
    1069              :         }
    1070              : 
    1071            0 :         if (verbose != 0) {
    1072            0 :             mbedtls_printf("passed\n");
    1073              :         }
    1074              :     }
    1075              : 
    1076            0 :     if (verbose != 0) {
    1077            0 :         mbedtls_printf("\n");
    1078              :     }
    1079              : 
    1080            0 :     goto exit;
    1081              : 
    1082            0 : fail:
    1083            0 :     if (verbose != 0) {
    1084            0 :         mbedtls_printf("failed\n");
    1085              :     }
    1086              : 
    1087            0 : exit:
    1088            0 :     mbedtls_sha512_free(&ctx);
    1089            0 :     mbedtls_free(buf);
    1090              : 
    1091            0 :     return ret;
    1092              : }
    1093              : 
    1094              : #if defined(MBEDTLS_SHA512_C)
    1095            0 : int mbedtls_sha512_self_test(int verbose)
    1096              : {
    1097            0 :     return mbedtls_sha512_common_self_test(verbose, 0);
    1098              : }
    1099              : #endif /* MBEDTLS_SHA512_C */
    1100              : 
    1101              : #if defined(MBEDTLS_SHA384_C)
    1102            0 : int mbedtls_sha384_self_test(int verbose)
    1103              : {
    1104            0 :     return mbedtls_sha512_common_self_test(verbose, 1);
    1105              : }
    1106              : #endif /* MBEDTLS_SHA384_C */
    1107              : 
    1108              : #undef ARRAY_LENGTH
    1109              : 
    1110              : #endif /* MBEDTLS_SELF_TEST */
    1111              : 
    1112              : #endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */
        

Generated by: LCOV version 2.0-1