Coverage Report

Created: 2024-01-20 12:33

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