Coverage Report

Created: 2025-03-01 06:26

/src/mbedtls/library/sha512.c
Line
Count
Source (jump to first uncovered line)
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
448
  #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
364
#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
280
{
215
280
    MBEDTLS_PUT_UINT64_BE(n, b, i);
216
280
}
217
#else
218
#define sha512_put_uint64_be    MBEDTLS_PUT_UINT64_BE
219
#endif /* MBEDTLS_SHA512_SMALLER */
220
221
void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
222
56
{
223
56
    memset(ctx, 0, sizeof(mbedtls_sha512_context));
224
56
}
225
226
void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
227
84
{
228
84
    if (ctx == NULL) {
229
0
        return;
230
0
    }
231
232
84
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
233
84
}
234
235
void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
236
                          const mbedtls_sha512_context *src)
237
0
{
238
0
    *dst = *src;
239
0
}
240
241
/*
242
 * SHA-512 context setup
243
 */
244
int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
245
56
{
246
56
#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
247
56
    if (is384 != 0 && is384 != 1) {
248
0
        return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
249
0
    }
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
56
    ctx->total[0] = 0;
261
56
    ctx->total[1] = 0;
262
263
56
    if (is384 == 0) {
264
56
#if defined(MBEDTLS_SHA512_C)
265
56
        ctx->state[0] = UL64(0x6A09E667F3BCC908);
266
56
        ctx->state[1] = UL64(0xBB67AE8584CAA73B);
267
56
        ctx->state[2] = UL64(0x3C6EF372FE94F82B);
268
56
        ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
269
56
        ctx->state[4] = UL64(0x510E527FADE682D1);
270
56
        ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
271
56
        ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
272
56
        ctx->state[7] = UL64(0x5BE0CD19137E2179);
273
56
#endif /* MBEDTLS_SHA512_C */
274
56
    } else {
275
0
#if defined(MBEDTLS_SHA384_C)
276
0
        ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
277
0
        ctx->state[1] = UL64(0x629A292A367CD507);
278
0
        ctx->state[2] = UL64(0x9159015A3070DD17);
279
0
        ctx->state[3] = UL64(0x152FECD8F70E5939);
280
0
        ctx->state[4] = UL64(0x67332667FFC00B31);
281
0
        ctx->state[5] = UL64(0x8EB44A8768581511);
282
0
        ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
283
0
        ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
284
0
#endif /* MBEDTLS_SHA384_C */
285
0
    }
286
287
56
#if defined(MBEDTLS_SHA384_C)
288
56
    ctx->is384 = is384;
289
56
#endif
290
291
56
    return 0;
292
56
}
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
28
#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
int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
602
                                      const unsigned char data[SHA512_BLOCK_SIZE])
603
56
{
604
56
    int i;
605
56
    struct {
606
56
        uint64_t temp1, temp2, W[80];
607
56
        uint64_t A[8];
608
56
    } local;
609
610
48.3k
#define  SHR(x, n) ((x) >> (n))
611
41.2k
#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
612
613
3.58k
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
614
3.58k
#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^  SHR(x, 6))
615
616
4.48k
#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
617
4.48k
#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
618
619
4.48k
#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
620
4.48k
#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
621
622
56
#define P(a, b, c, d, e, f, g, h, x, K)                                      \
623
4.48k
    do                                                              \
624
4.48k
    {                                                               \
625
4.48k
        local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x);    \
626
4.48k
        local.temp2 = S2(a) + F0((a), (b), (c));                      \
627
4.48k
        (d) += local.temp1; (h) = local.temp1 + local.temp2;        \
628
4.48k
    } while (0)
629
630
504
    for (i = 0; i < 8; i++) {
631
448
        local.A[i] = ctx->state[i];
632
448
    }
633
634
56
#if defined(MBEDTLS_SHA512_SMALLER)
635
4.53k
    for (i = 0; i < 80; i++) {
636
4.48k
        if (i < 16) {
637
896
            local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
638
3.58k
        } else {
639
3.58k
            local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
640
3.58k
                         S0(local.W[i - 15]) + local.W[i - 16];
641
3.58k
        }
642
643
4.48k
        P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
644
4.48k
          local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
645
646
4.48k
        local.temp1 = local.A[7]; local.A[7] = local.A[6];
647
4.48k
        local.A[6] = local.A[5]; local.A[5] = local.A[4];
648
4.48k
        local.A[4] = local.A[3]; local.A[3] = local.A[2];
649
4.48k
        local.A[2] = local.A[1]; local.A[1] = local.A[0];
650
4.48k
        local.A[0] = local.temp1;
651
4.48k
    }
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
504
    for (i = 0; i < 8; i++) {
684
448
        ctx->state[i] += local.A[i];
685
448
    }
686
687
    /* Zeroise buffers and variables to clear sensitive data from memory. */
688
56
    mbedtls_platform_zeroize(&local, sizeof(local));
689
690
56
    return 0;
691
56
}
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
static size_t mbedtls_internal_sha512_process_many_c(
699
    mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
700
28
{
701
28
    size_t processed = 0;
702
703
56
    while (len >= SHA512_BLOCK_SIZE) {
704
28
        if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
705
0
            return 0;
706
0
        }
707
708
28
        data += SHA512_BLOCK_SIZE;
709
28
        len  -= SHA512_BLOCK_SIZE;
710
711
28
        processed += SHA512_BLOCK_SIZE;
712
28
    }
713
714
28
    return processed;
715
28
}
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
int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
761
                          const unsigned char *input,
762
                          size_t ilen)
763
84
{
764
84
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
765
84
    size_t fill;
766
84
    unsigned int left;
767
768
84
    if (ilen == 0) {
769
0
        return 0;
770
0
    }
771
772
84
    left = (unsigned int) (ctx->total[0] & 0x7F);
773
84
    fill = SHA512_BLOCK_SIZE - left;
774
775
84
    ctx->total[0] += (uint64_t) ilen;
776
777
84
    if (ctx->total[0] < (uint64_t) ilen) {
778
0
        ctx->total[1]++;
779
0
    }
780
781
84
    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
0
        }
787
788
0
        input += fill;
789
0
        ilen  -= fill;
790
0
        left = 0;
791
0
    }
792
793
112
    while (ilen >= SHA512_BLOCK_SIZE) {
794
28
        size_t processed =
795
28
            mbedtls_internal_sha512_process_many(ctx, input, ilen);
796
28
        if (processed < SHA512_BLOCK_SIZE) {
797
0
            return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
798
0
        }
799
800
28
        input += processed;
801
28
        ilen  -= processed;
802
28
    }
803
804
84
    if (ilen > 0) {
805
56
        memcpy((void *) (ctx->buffer + left), input, ilen);
806
56
    }
807
808
84
    return 0;
809
84
}
810
811
/*
812
 * SHA-512 final digest
813
 */
814
int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
815
                          unsigned char *output)
816
28
{
817
28
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
818
28
    unsigned used;
819
28
    uint64_t high, low;
820
28
    int truncated = 0;
821
822
    /*
823
     * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
824
     */
825
28
    used = ctx->total[0] & 0x7F;
826
827
28
    ctx->buffer[used++] = 0x80;
828
829
28
    if (used <= 112) {
830
        /* Enough room for padding + length in current block */
831
28
        memset(ctx->buffer + used, 0, 112 - used);
832
28
    } 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
0
        }
839
840
0
        memset(ctx->buffer, 0, 112);
841
0
    }
842
843
    /*
844
     * Add message length
845
     */
846
28
    high = (ctx->total[0] >> 61)
847
28
           | (ctx->total[1] <<  3);
848
28
    low  = (ctx->total[0] <<  3);
849
850
28
    sha512_put_uint64_be(high, ctx->buffer, 112);
851
28
    sha512_put_uint64_be(low,  ctx->buffer, 120);
852
853
28
    if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
854
0
        goto exit;
855
0
    }
856
857
    /*
858
     * Output final state
859
     */
860
28
    sha512_put_uint64_be(ctx->state[0], output,  0);
861
28
    sha512_put_uint64_be(ctx->state[1], output,  8);
862
28
    sha512_put_uint64_be(ctx->state[2], output, 16);
863
28
    sha512_put_uint64_be(ctx->state[3], output, 24);
864
28
    sha512_put_uint64_be(ctx->state[4], output, 32);
865
28
    sha512_put_uint64_be(ctx->state[5], output, 40);
866
867
28
#if defined(MBEDTLS_SHA384_C)
868
28
    truncated = ctx->is384;
869
28
#endif
870
28
    if (!truncated) {
871
28
        sha512_put_uint64_be(ctx->state[6], output, 48);
872
28
        sha512_put_uint64_be(ctx->state[7], output, 56);
873
28
    }
874
875
28
    ret = 0;
876
877
28
exit:
878
28
    mbedtls_sha512_free(ctx);
879
28
    return ret;
880
28
}
881
882
#endif /* !MBEDTLS_SHA512_ALT */
883
884
/*
885
 * output = SHA-512( input buffer )
886
 */
887
int mbedtls_sha512(const unsigned char *input,
888
                   size_t ilen,
889
                   unsigned char *output,
890
                   int is384)
891
28
{
892
28
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
893
28
    mbedtls_sha512_context ctx;
894
895
28
#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
896
28
    if (is384 != 0 && is384 != 1) {
897
0
        return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
898
0
    }
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
28
    mbedtls_sha512_init(&ctx);
910
911
28
    if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
912
0
        goto exit;
913
0
    }
914
915
28
    if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
916
0
        goto exit;
917
0
    }
918
919
28
    if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
920
0
        goto exit;
921
0
    }
922
923
28
exit:
924
28
    mbedtls_sha512_free(&ctx);
925
926
28
    return ret;
927
28
}
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
static int mbedtls_sha512_common_self_test(int verbose, int is384)
1011
0
{
1012
0
    int i, buflen, ret = 0;
1013
0
    unsigned char *buf;
1014
0
    unsigned char sha512sum[64];
1015
0
    mbedtls_sha512_context ctx;
1016
1017
0
#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
0
        }
1030
1031
0
        return 1;
1032
0
    }
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
0
        }
1040
1041
0
        if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
1042
0
            goto fail;
1043
0
        }
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
0
                }
1053
0
            }
1054
0
        } 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
0
            }
1060
0
        }
1061
1062
0
        if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1063
0
            goto fail;
1064
0
        }
1065
1066
0
        if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
1067
0
            ret = 1;
1068
0
            goto fail;
1069
0
        }
1070
1071
0
        if (verbose != 0) {
1072
0
            mbedtls_printf("passed\n");
1073
0
        }
1074
0
    }
1075
1076
0
    if (verbose != 0) {
1077
0
        mbedtls_printf("\n");
1078
0
    }
1079
1080
0
    goto exit;
1081
1082
0
fail:
1083
0
    if (verbose != 0) {
1084
0
        mbedtls_printf("failed\n");
1085
0
    }
1086
1087
0
exit:
1088
0
    mbedtls_sha512_free(&ctx);
1089
0
    mbedtls_free(buf);
1090
1091
0
    return ret;
1092
0
}
1093
1094
#if defined(MBEDTLS_SHA512_C)
1095
int mbedtls_sha512_self_test(int verbose)
1096
0
{
1097
0
    return mbedtls_sha512_common_self_test(verbose, 0);
1098
0
}
1099
#endif /* MBEDTLS_SHA512_C */
1100
1101
#if defined(MBEDTLS_SHA384_C)
1102
int mbedtls_sha384_self_test(int verbose)
1103
0
{
1104
0
    return mbedtls_sha512_common_self_test(verbose, 1);
1105
0
}
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 */