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