xref: /third_party/mbedtls/library/sha512.c (revision a8e1175b)
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)
129static 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
137static 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
162static jmp_buf return_from_sigill;
163
164/*
165 * A64 SHA512 support detection via SIGILL
166 */
167static void sigill_handler(int signal)
168{
169    (void) signal;
170    longjmp(return_from_sigill, 1);
171}
172
173static 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)
213static 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
221void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
222{
223    memset(ctx, 0, sizeof(mbedtls_sha512_context));
224}
225
226void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
227{
228    if (ctx == NULL) {
229        return;
230    }
231
232    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
233}
234
235void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
236                          const mbedtls_sha512_context *src)
237{
238    *dst = *src;
239}
240
241/*
242 * SHA-512 context setup
243 */
244int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
245{
246#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
247    if (is384 != 0 && is384 != 1) {
248        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    ctx->total[0] = 0;
261    ctx->total[1] = 0;
262
263    if (is384 == 0) {
264#if defined(MBEDTLS_SHA512_C)
265        ctx->state[0] = UL64(0x6A09E667F3BCC908);
266        ctx->state[1] = UL64(0xBB67AE8584CAA73B);
267        ctx->state[2] = UL64(0x3C6EF372FE94F82B);
268        ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
269        ctx->state[4] = UL64(0x510E527FADE682D1);
270        ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
271        ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
272        ctx->state[7] = UL64(0x5BE0CD19137E2179);
273#endif /* MBEDTLS_SHA512_C */
274    } else {
275#if defined(MBEDTLS_SHA384_C)
276        ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
277        ctx->state[1] = UL64(0x629A292A367CD507);
278        ctx->state[2] = UL64(0x9159015A3070DD17);
279        ctx->state[3] = UL64(0x152FECD8F70E5939);
280        ctx->state[4] = UL64(0x67332667FFC00B31);
281        ctx->state[5] = UL64(0x8EB44A8768581511);
282        ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
283        ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
284#endif /* MBEDTLS_SHA384_C */
285    }
286
287#if defined(MBEDTLS_SHA384_C)
288    ctx->is384 = is384;
289#endif
290
291    return 0;
292}
293
294#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
295
296/*
297 * Round constants
298 */
299static 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))
359static 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}
364static 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}
369static 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}
374static 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
381static 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 */
564static
565#endif
566int 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 */
599static
600#endif
601int 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    for (i = 0; i < 8; i++) {
631        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    for (i = 0; i < 16; i++) {
654        local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
655    }
656
657    for (; i < 80; i++) {
658        local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
659                     S0(local.W[i - 15]) + local.W[i - 16];
660    }
661
662    i = 0;
663    do {
664        P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
665          local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
666        P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
667          local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
668        P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
669          local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
670        P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
671          local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
672        P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
673          local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
674        P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
675          local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
676        P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
677          local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
678        P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
679          local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
680    } while (i < 80);
681#endif /* MBEDTLS_SHA512_SMALLER */
682
683    for (i = 0; i < 8; i++) {
684        ctx->state[i] += local.A[i];
685    }
686
687    /* Zeroise buffers and variables to clear sensitive data from memory. */
688    mbedtls_platform_zeroize(&local, sizeof(local));
689
690    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
698static size_t mbedtls_internal_sha512_process_many_c(
699    mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
700{
701    size_t processed = 0;
702
703    while (len >= SHA512_BLOCK_SIZE) {
704        if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
705            return 0;
706        }
707
708        data += SHA512_BLOCK_SIZE;
709        len  -= SHA512_BLOCK_SIZE;
710
711        processed += SHA512_BLOCK_SIZE;
712    }
713
714    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
722static 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
735static 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
745int 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 */
760int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
761                          const unsigned char *input,
762                          size_t ilen)
763{
764    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
765    size_t fill;
766    unsigned int left;
767
768    if (ilen == 0) {
769        return 0;
770    }
771
772    left = (unsigned int) (ctx->total[0] & 0x7F);
773    fill = SHA512_BLOCK_SIZE - left;
774
775    ctx->total[0] += (uint64_t) ilen;
776
777    if (ctx->total[0] < (uint64_t) ilen) {
778        ctx->total[1]++;
779    }
780
781    if (left && ilen >= fill) {
782        memcpy((void *) (ctx->buffer + left), input, fill);
783
784        if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
785            return ret;
786        }
787
788        input += fill;
789        ilen  -= fill;
790        left = 0;
791    }
792
793    while (ilen >= SHA512_BLOCK_SIZE) {
794        size_t processed =
795            mbedtls_internal_sha512_process_many(ctx, input, ilen);
796        if (processed < SHA512_BLOCK_SIZE) {
797            return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
798        }
799
800        input += processed;
801        ilen  -= processed;
802    }
803
804    if (ilen > 0) {
805        memcpy((void *) (ctx->buffer + left), input, ilen);
806    }
807
808    return 0;
809}
810
811/*
812 * SHA-512 final digest
813 */
814int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
815                          unsigned char *output)
816{
817    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
818    unsigned used;
819    uint64_t high, low;
820    int truncated = 0;
821
822    /*
823     * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
824     */
825    used = ctx->total[0] & 0x7F;
826
827    ctx->buffer[used++] = 0x80;
828
829    if (used <= 112) {
830        /* Enough room for padding + length in current block */
831        memset(ctx->buffer + used, 0, 112 - used);
832    } else {
833        /* We'll need an extra block */
834        memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
835
836        if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
837            goto exit;
838        }
839
840        memset(ctx->buffer, 0, 112);
841    }
842
843    /*
844     * Add message length
845     */
846    high = (ctx->total[0] >> 61)
847           | (ctx->total[1] <<  3);
848    low  = (ctx->total[0] <<  3);
849
850    sha512_put_uint64_be(high, ctx->buffer, 112);
851    sha512_put_uint64_be(low,  ctx->buffer, 120);
852
853    if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
854        goto exit;
855    }
856
857    /*
858     * Output final state
859     */
860    sha512_put_uint64_be(ctx->state[0], output,  0);
861    sha512_put_uint64_be(ctx->state[1], output,  8);
862    sha512_put_uint64_be(ctx->state[2], output, 16);
863    sha512_put_uint64_be(ctx->state[3], output, 24);
864    sha512_put_uint64_be(ctx->state[4], output, 32);
865    sha512_put_uint64_be(ctx->state[5], output, 40);
866
867#if defined(MBEDTLS_SHA384_C)
868    truncated = ctx->is384;
869#endif
870    if (!truncated) {
871        sha512_put_uint64_be(ctx->state[6], output, 48);
872        sha512_put_uint64_be(ctx->state[7], output, 56);
873    }
874
875    ret = 0;
876
877exit:
878    mbedtls_sha512_free(ctx);
879    return ret;
880}
881
882#endif /* !MBEDTLS_SHA512_ALT */
883
884/*
885 * output = SHA-512( input buffer )
886 */
887int mbedtls_sha512(const unsigned char *input,
888                   size_t ilen,
889                   unsigned char *output,
890                   int is384)
891{
892    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
893    mbedtls_sha512_context ctx;
894
895#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
896    if (is384 != 0 && is384 != 1) {
897        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    mbedtls_sha512_init(&ctx);
910
911    if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
912        goto exit;
913    }
914
915    if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
916        goto exit;
917    }
918
919    if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
920        goto exit;
921    }
922
923exit:
924    mbedtls_sha512_free(&ctx);
925
926    return ret;
927}
928
929#if defined(MBEDTLS_SELF_TEST)
930
931/*
932 * FIPS-180-2 test vectors
933 */
934static const unsigned char sha_test_buf[3][113] =
935{
936    { "abc" },
937    {
938        "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
939    },
940    { "" }
941};
942
943static const size_t sha_test_buflen[3] =
944{
945    3, 112, 1000
946};
947
948typedef const unsigned char (sha_test_sum_t)[64];
949
950/*
951 * SHA-384 test vectors
952 */
953#if defined(MBEDTLS_SHA384_C)
954static 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)
981static 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
1010static int mbedtls_sha512_common_self_test(int verbose, int is384)
1011{
1012    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    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    buf = mbedtls_calloc(1024, sizeof(unsigned char));
1026    if (NULL == buf) {
1027        if (verbose != 0) {
1028            mbedtls_printf("Buffer allocation failed\n");
1029        }
1030
1031        return 1;
1032    }
1033
1034    mbedtls_sha512_init(&ctx);
1035
1036    for (i = 0; i < 3; i++) {
1037        if (verbose != 0) {
1038            mbedtls_printf("  SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1039        }
1040
1041        if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
1042            goto fail;
1043        }
1044
1045        if (i == 2) {
1046            memset(buf, 'a', buflen = 1000);
1047
1048            for (int j = 0; j < 1000; j++) {
1049                ret = mbedtls_sha512_update(&ctx, buf, buflen);
1050                if (ret != 0) {
1051                    goto fail;
1052                }
1053            }
1054        } else {
1055            ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1056                                        sha_test_buflen[i]);
1057            if (ret != 0) {
1058                goto fail;
1059            }
1060        }
1061
1062        if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1063            goto fail;
1064        }
1065
1066        if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
1067            ret = 1;
1068            goto fail;
1069        }
1070
1071        if (verbose != 0) {
1072            mbedtls_printf("passed\n");
1073        }
1074    }
1075
1076    if (verbose != 0) {
1077        mbedtls_printf("\n");
1078    }
1079
1080    goto exit;
1081
1082fail:
1083    if (verbose != 0) {
1084        mbedtls_printf("failed\n");
1085    }
1086
1087exit:
1088    mbedtls_sha512_free(&ctx);
1089    mbedtls_free(buf);
1090
1091    return ret;
1092}
1093
1094#if defined(MBEDTLS_SHA512_C)
1095int mbedtls_sha512_self_test(int verbose)
1096{
1097    return mbedtls_sha512_common_self_test(verbose, 0);
1098}
1099#endif /* MBEDTLS_SHA512_C */
1100
1101#if defined(MBEDTLS_SHA384_C)
1102int mbedtls_sha384_self_test(int verbose)
1103{
1104    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 */
1113