Coverage Report

Created: 2024-08-01 14:30

/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
280k
  #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
996k
#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
134k
#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
37.6k
{
168
37.6k
    memset(ctx, 0, sizeof(mbedtls_sha512_context));
169
37.6k
}
170
171
void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
172
37.6k
{
173
37.6k
    if (ctx == NULL) {
174
0
        return;
175
0
    }
176
177
37.6k
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
178
37.6k
}
179
180
void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
181
                          const mbedtls_sha512_context *src)
182
6.98k
{
183
6.98k
    *dst = *src;
184
6.98k
}
185
186
/*
187
 * SHA-512 context setup
188
 */
189
int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
190
35.0k
{
191
35.0k
#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
192
35.0k
    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
35.0k
    ctx->total[0] = 0;
206
35.0k
    ctx->total[1] = 0;
207
208
35.0k
    if (is384 == 0) {
209
362
#if defined(MBEDTLS_SHA512_C)
210
362
        ctx->state[0] = UL64(0x6A09E667F3BCC908);
211
362
        ctx->state[1] = UL64(0xBB67AE8584CAA73B);
212
362
        ctx->state[2] = UL64(0x3C6EF372FE94F82B);
213
362
        ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
214
362
        ctx->state[4] = UL64(0x510E527FADE682D1);
215
362
        ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
216
362
        ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
217
362
        ctx->state[7] = UL64(0x5BE0CD19137E2179);
218
362
#endif /* MBEDTLS_SHA512_C */
219
34.6k
    } else {
220
34.6k
#if defined(MBEDTLS_SHA384_C)
221
34.6k
        ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
222
34.6k
        ctx->state[1] = UL64(0x629A292A367CD507);
223
34.6k
        ctx->state[2] = UL64(0x9159015A3070DD17);
224
34.6k
        ctx->state[3] = UL64(0x152FECD8F70E5939);
225
34.6k
        ctx->state[4] = UL64(0x67332667FFC00B31);
226
34.6k
        ctx->state[5] = UL64(0x8EB44A8768581511);
227
34.6k
        ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
228
34.6k
        ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
229
34.6k
#endif /* MBEDTLS_SHA384_C */
230
34.6k
    }
231
232
35.0k
#if defined(MBEDTLS_SHA384_C)
233
35.0k
    ctx->is384 = is384;
234
35.0k
#endif
235
236
35.0k
    return 0;
237
35.0k
}
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
182k
#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
221k
{
540
221k
    int i;
541
221k
    struct {
542
221k
        uint64_t temp1, temp2, W[80];
543
221k
        uint64_t A[8];
544
221k
    } local;
545
546
191M
#define  SHR(x, n) ((x) >> (n))
547
163M
#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
548
549
14.1M
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
550
14.1M
#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^  SHR(x, 6))
551
552
17.7M
#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
553
17.7M
#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
554
555
17.7M
#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
556
17.7M
#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
557
558
221k
#define P(a, b, c, d, e, f, g, h, x, K)                                      \
559
17.7M
    do                                                              \
560
17.7M
    {                                                               \
561
17.7M
        local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x);    \
562
17.7M
        local.temp2 = S2(a) + F0((a), (b), (c));                      \
563
17.7M
        (d) += local.temp1; (h) = local.temp1 + local.temp2;        \
564
17.7M
    } while (0)
565
566
1.99M
    for (i = 0; i < 8; i++) {
567
1.77M
        local.A[i] = ctx->state[i];
568
1.77M
    }
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
3.76M
    for (i = 0; i < 16; i++) {
590
3.54M
        local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
591
3.54M
    }
592
593
14.4M
    for (; i < 80; i++) {
594
14.1M
        local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
595
14.1M
                     S0(local.W[i - 15]) + local.W[i - 16];
596
14.1M
    }
597
598
221k
    i = 0;
599
2.21M
    do {
600
2.21M
        P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
601
2.21M
          local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
602
2.21M
        P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
603
2.21M
          local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
604
2.21M
        P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
605
2.21M
          local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
606
2.21M
        P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
607
2.21M
          local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
608
2.21M
        P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
609
2.21M
          local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
610
2.21M
        P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
611
2.21M
          local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
612
2.21M
        P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
613
2.21M
          local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
614
2.21M
        P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
615
2.21M
          local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
616
2.21M
    } while (i < 80);
617
221k
#endif /* MBEDTLS_SHA512_SMALLER */
618
619
1.99M
    for (i = 0; i < 8; i++) {
620
1.77M
        ctx->state[i] += local.A[i];
621
1.77M
    }
622
623
    /* Zeroise buffers and variables to clear sensitive data from memory. */
624
221k
    mbedtls_platform_zeroize(&local, sizeof(local));
625
626
221k
    return 0;
627
221k
}
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
40.3k
{
637
40.3k
    size_t processed = 0;
638
639
222k
    while (len >= SHA512_BLOCK_SIZE) {
640
182k
        if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
641
0
            return 0;
642
0
        }
643
644
182k
        data += SHA512_BLOCK_SIZE;
645
182k
        len  -= SHA512_BLOCK_SIZE;
646
647
182k
        processed += SHA512_BLOCK_SIZE;
648
182k
    }
649
650
40.3k
    return processed;
651
40.3k
}
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
71.7k
{
700
71.7k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
701
71.7k
    size_t fill;
702
71.7k
    unsigned int left;
703
704
71.7k
    if (ilen == 0) {
705
17
        return 0;
706
17
    }
707
708
71.7k
    left = (unsigned int) (ctx->total[0] & 0x7F);
709
71.7k
    fill = SHA512_BLOCK_SIZE - left;
710
711
71.7k
    ctx->total[0] += (uint64_t) ilen;
712
713
71.7k
    if (ctx->total[0] < (uint64_t) ilen) {
714
0
        ctx->total[1]++;
715
0
    }
716
717
71.7k
    if (left && ilen >= fill) {
718
20.2k
        memcpy((void *) (ctx->buffer + left), input, fill);
719
720
20.2k
        if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
721
0
            return ret;
722
0
        }
723
724
20.2k
        input += fill;
725
20.2k
        ilen  -= fill;
726
20.2k
        left = 0;
727
20.2k
    }
728
729
112k
    while (ilen >= SHA512_BLOCK_SIZE) {
730
40.3k
        size_t processed =
731
40.3k
            mbedtls_internal_sha512_process_many(ctx, input, ilen);
732
40.3k
        if (processed < SHA512_BLOCK_SIZE) {
733
0
            return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
734
0
        }
735
736
40.3k
        input += processed;
737
40.3k
        ilen  -= processed;
738
40.3k
    }
739
740
71.7k
    if (ilen > 0) {
741
62.2k
        memcpy((void *) (ctx->buffer + left), input, ilen);
742
62.2k
    }
743
744
71.7k
    return 0;
745
71.7k
}
746
747
/*
748
 * SHA-512 final digest
749
 */
750
int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
751
                          unsigned char *output)
752
16.7k
{
753
16.7k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
754
16.7k
    unsigned used;
755
16.7k
    uint64_t high, low;
756
757
    /*
758
     * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
759
     */
760
16.7k
    used = ctx->total[0] & 0x7F;
761
762
16.7k
    ctx->buffer[used++] = 0x80;
763
764
16.7k
    if (used <= 112) {
765
        /* Enough room for padding + length in current block */
766
14.6k
        memset(ctx->buffer + used, 0, 112 - used);
767
14.6k
    } else {
768
        /* We'll need an extra block */
769
2.16k
        memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
770
771
2.16k
        if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
772
0
            return ret;
773
0
        }
774
775
2.16k
        memset(ctx->buffer, 0, 112);
776
2.16k
    }
777
778
    /*
779
     * Add message length
780
     */
781
16.7k
    high = (ctx->total[0] >> 61)
782
16.7k
           | (ctx->total[1] <<  3);
783
16.7k
    low  = (ctx->total[0] <<  3);
784
785
16.7k
    sha512_put_uint64_be(high, ctx->buffer, 112);
786
16.7k
    sha512_put_uint64_be(low,  ctx->buffer, 120);
787
788
16.7k
    if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
789
0
        return ret;
790
0
    }
791
792
    /*
793
     * Output final state
794
     */
795
16.7k
    sha512_put_uint64_be(ctx->state[0], output,  0);
796
16.7k
    sha512_put_uint64_be(ctx->state[1], output,  8);
797
16.7k
    sha512_put_uint64_be(ctx->state[2], output, 16);
798
16.7k
    sha512_put_uint64_be(ctx->state[3], output, 24);
799
16.7k
    sha512_put_uint64_be(ctx->state[4], output, 32);
800
16.7k
    sha512_put_uint64_be(ctx->state[5], output, 40);
801
802
16.7k
    int truncated = 0;
803
16.7k
#if defined(MBEDTLS_SHA384_C)
804
16.7k
    truncated = ctx->is384;
805
16.7k
#endif
806
16.7k
    if (!truncated) {
807
362
        sha512_put_uint64_be(ctx->state[6], output, 48);
808
362
        sha512_put_uint64_be(ctx->state[7], output, 56);
809
362
    }
810
811
16.7k
    return 0;
812
16.7k
}
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 */