blob: 6dcea8da5d5c55b3110e403030756c2e65db4d1f [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
Tom Van Eyckc1633172024-04-09 18:44:13 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Jens Wiklander817466c2018-05-22 13:49:31 +02006 */
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
Jens Wiklander32b31802023-10-06 16:59:46 +020013#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
14 defined(__clang__) && __clang_major__ >= 7
15/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
16 *
17 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
18 * these are normally only enabled by the -march option on the command line.
19 * By defining the macros ourselves we gain access to those declarations without
20 * requiring -march on the command line.
21 *
Tom Van Eyckc1633172024-04-09 18:44:13 +020022 * `arm_neon.h` is included by common.h, so we put these defines
Jens Wiklander32b31802023-10-06 16:59:46 +020023 * at the top of this file, before any includes.
24 */
25#define __ARM_FEATURE_SHA512 1
26#define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG
27#endif
28
Jerome Forissier79013242021-07-28 10:24:04 +020029#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020030
Jens Wiklander32b31802023-10-06 16:59:46 +020031#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Jens Wiklander817466c2018-05-22 13:49:31 +020032
33#include "mbedtls/sha512.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010034#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020035#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020036
37#if defined(_MSC_VER) || defined(__WATCOMC__)
38 #define UL64(x) x##ui64
39#else
40 #define UL64(x) x##ULL
41#endif
42
43#include <string.h>
44
Jens Wiklander817466c2018-05-22 13:49:31 +020045#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020046
Jens Wiklander32b31802023-10-06 16:59:46 +020047#if defined(__aarch64__)
48# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
49 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
50/* *INDENT-OFF* */
Tom Van Eyckc1633172024-04-09 18:44:13 +020051# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
52# error "Target does not support NEON instructions"
53# endif
Jens Wiklander32b31802023-10-06 16:59:46 +020054/*
55 * Best performance comes from most recent compilers, with intrinsics and -O3.
56 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
57 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
58 *
59 * GCC < 8 won't work at all (lacks the sha512 instructions)
60 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
61 *
62 * Clang < 7 won't work at all (lacks the sha512 instructions)
63 * Clang 7-12 don't have intrinsics (but we work around that with inline
64 * assembler) or __ARM_FEATURE_SHA512
65 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
66 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
67 */
68# if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
69 /* Test Clang first, as it defines __GNUC__ */
Tom Van Eyckc1633172024-04-09 18:44:13 +020070# if defined(__ARMCOMPILER_VERSION)
71# if __ARMCOMPILER_VERSION < 6090000
72# error "A more recent armclang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
73# elif __ARMCOMPILER_VERSION == 6090000
74# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
75# else
76# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
77# define MBEDTLS_POP_TARGET_PRAGMA
78# endif
79# elif defined(__clang__)
Jens Wiklander32b31802023-10-06 16:59:46 +020080# if __clang_major__ < 7
81# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
82# else
83# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
84# define MBEDTLS_POP_TARGET_PRAGMA
85# endif
86# elif defined(__GNUC__)
87# if __GNUC__ < 8
88# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
89# else
90# pragma GCC push_options
91# pragma GCC target ("arch=armv8.2-a+sha3")
92# define MBEDTLS_POP_TARGET_PRAGMA
93# endif
94# else
95# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
96# endif
97# endif
98/* *INDENT-ON* */
Jens Wiklander32b31802023-10-06 16:59:46 +020099# endif
100# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
101# if defined(__unix__)
102# if defined(__linux__)
103/* Our preferred method of detection is getauxval() */
104# include <sys/auxv.h>
Tom Van Eyckc1633172024-04-09 18:44:13 +0200105# if !defined(HWCAP_SHA512)
106/* The same header that declares getauxval() should provide the HWCAP_xxx
107 * constants to analyze its return value. However, the libc may be too
108 * old to have the constant that we need. So if it's missing, assume that
109 * the value is the same one used by the Linux kernel ABI.
110 */
111# define HWCAP_SHA512 (1 << 21)
112# endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200113# endif
114/* Use SIGILL on Unix, and fall back to it on Linux */
115# include <signal.h>
116# endif
117# endif
Tom Van Eyckc1633172024-04-09 18:44:13 +0200118#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Jens Wiklander32b31802023-10-06 16:59:46 +0200119# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
120# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
121#endif
122
123#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
124/*
125 * Capability detection code comes early, so we can disable
126 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
127 */
128#if defined(HWCAP_SHA512)
129static int mbedtls_a64_crypto_sha512_determine_support(void)
130{
131 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
132}
133#elif defined(__APPLE__)
134#include <sys/types.h>
135#include <sys/sysctl.h>
136
137static int mbedtls_a64_crypto_sha512_determine_support(void)
138{
139 int value = 0;
140 size_t value_len = sizeof(value);
141
142 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
143 NULL, 0);
144 return ret == 0 && value != 0;
145}
Tom Van Eyckc1633172024-04-09 18:44:13 +0200146#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Jens Wiklander32b31802023-10-06 16:59:46 +0200147/*
148 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
149 * available to pass to IsProcessorFeaturePresent() to check for
150 * SHA-512 support. So we fall back to the C code only.
151 */
152#if defined(_MSC_VER)
153#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
154#else
155#warning "No mechanism to detect A64_CRYPTO found, using C code only"
156#endif
157#elif defined(__unix__) && defined(SIG_SETMASK)
158/* Detection with SIGILL, setjmp() and longjmp() */
159#include <signal.h>
160#include <setjmp.h>
161
162static jmp_buf return_from_sigill;
163
164/*
165 * A64 SHA512 support detection via SIGILL
166 */
167static void sigill_handler(int signal)
168{
169 (void) signal;
170 longjmp(return_from_sigill, 1);
171}
172
173static int mbedtls_a64_crypto_sha512_determine_support(void)
174{
175 struct sigaction old_action, new_action;
176
177 sigset_t old_mask;
178 if (sigprocmask(0, NULL, &old_mask)) {
179 return 0;
180 }
181
182 sigemptyset(&new_action.sa_mask);
183 new_action.sa_flags = 0;
184 new_action.sa_handler = sigill_handler;
185
186 sigaction(SIGILL, &new_action, &old_action);
187
188 static int ret = 0;
189
190 if (setjmp(return_from_sigill) == 0) { /* First return only */
191 /* If this traps, we will return a second time from setjmp() with 1 */
192 asm ("sha512h q0, q0, v0.2d" : : : "v0");
193 ret = 1;
194 }
195
196 sigaction(SIGILL, &old_action, NULL);
197 sigprocmask(SIG_SETMASK, &old_mask, NULL);
198
199 return ret;
200}
201#else
202#warning "No mechanism to detect A64_CRYPTO found, using C code only"
203#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
204#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
205
206#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Jens Wiklander817466c2018-05-22 13:49:31 +0200207
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100208#if !defined(MBEDTLS_SHA512_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +0200209
Jens Wiklander32b31802023-10-06 16:59:46 +0200210#define SHA512_BLOCK_SIZE 128
211
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200212#if defined(MBEDTLS_SHA512_SMALLER)
Jens Wiklander32b31802023-10-06 16:59:46 +0200213static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200214{
Jerome Forissier039e02d2022-08-09 17:10:15 +0200215 MBEDTLS_PUT_UINT64_BE(n, b, i);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200216}
217#else
Jerome Forissier039e02d2022-08-09 17:10:15 +0200218#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200219#endif /* MBEDTLS_SHA512_SMALLER */
220
Jens Wiklander32b31802023-10-06 16:59:46 +0200221void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200222{
Jens Wiklander32b31802023-10-06 16:59:46 +0200223 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200224}
225
Jens Wiklander32b31802023-10-06 16:59:46 +0200226void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200227{
Jens Wiklander32b31802023-10-06 16:59:46 +0200228 if (ctx == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200229 return;
Jens Wiklander32b31802023-10-06 16:59:46 +0200230 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200231
Jens Wiklander32b31802023-10-06 16:59:46 +0200232 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200233}
234
Jens Wiklander32b31802023-10-06 16:59:46 +0200235void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
236 const mbedtls_sha512_context *src)
Jens Wiklander817466c2018-05-22 13:49:31 +0200237{
238 *dst = *src;
239}
240
241/*
242 * SHA-512 context setup
243 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200244int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200245{
Jens Wiklander32b31802023-10-06 16:59:46 +0200246#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
247 if (is384 != 0 && is384 != 1) {
248 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
249 }
250#elif defined(MBEDTLS_SHA512_C)
251 if (is384 != 0) {
252 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
253 }
254#else /* defined MBEDTLS_SHA384_C only */
255 if (is384 == 0) {
256 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
257 }
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200258#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100259
Jens Wiklander817466c2018-05-22 13:49:31 +0200260 ctx->total[0] = 0;
261 ctx->total[1] = 0;
262
Jens Wiklander32b31802023-10-06 16:59:46 +0200263 if (is384 == 0) {
264#if defined(MBEDTLS_SHA512_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200265 ctx->state[0] = UL64(0x6A09E667F3BCC908);
266 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
267 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
268 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
269 ctx->state[4] = UL64(0x510E527FADE682D1);
270 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
271 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
272 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Jens Wiklander32b31802023-10-06 16:59:46 +0200273#endif /* MBEDTLS_SHA512_C */
274 } else {
275#if defined(MBEDTLS_SHA384_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200276 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
277 ctx->state[1] = UL64(0x629A292A367CD507);
278 ctx->state[2] = UL64(0x9159015A3070DD17);
279 ctx->state[3] = UL64(0x152FECD8F70E5939);
280 ctx->state[4] = UL64(0x67332667FFC00B31);
281 ctx->state[5] = UL64(0x8EB44A8768581511);
282 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
283 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Jens Wiklander32b31802023-10-06 16:59:46 +0200284#endif /* MBEDTLS_SHA384_C */
Jens Wiklander817466c2018-05-22 13:49:31 +0200285 }
286
Jens Wiklander32b31802023-10-06 16:59:46 +0200287#if defined(MBEDTLS_SHA384_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200288 ctx->is384 = is384;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200289#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100290
Jens Wiklander32b31802023-10-06 16:59:46 +0200291 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200292}
293
294#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
295
296/*
297 * Round constants
298 */
299static const uint64_t K[80] =
300{
301 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
302 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
303 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
304 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
305 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
306 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
307 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
308 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
309 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
310 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
311 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
312 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
313 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
314 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
315 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
316 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
317 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
318 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
319 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
320 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
321 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
322 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
323 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
324 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
325 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
326 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
327 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
328 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
329 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
330 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
331 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
332 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
333 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
334 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
335 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
336 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
337 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
338 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
339 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
340 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
341};
Jens Wiklander32b31802023-10-06 16:59:46 +0200342#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200343
Jens Wiklander32b31802023-10-06 16:59:46 +0200344#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
345 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
346
347#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
348# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
349# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
350#endif
351
352/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
353 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
354 */
355
356#if defined(__clang__) && \
357 (__clang_major__ < 13 || \
358 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
359static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
360{
361 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
362 return x;
363}
364static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
365{
366 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
367 return x;
368}
369static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
370{
371 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
372 return x;
373}
374static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
375{
376 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
377 return x;
378}
379#endif /* __clang__ etc */
380
381static size_t mbedtls_internal_sha512_process_many_a64_crypto(
382 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
383{
384 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
385 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
386 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
387 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
388
389 size_t processed = 0;
390
391 for (;
392 len >= SHA512_BLOCK_SIZE;
393 processed += SHA512_BLOCK_SIZE,
394 msg += SHA512_BLOCK_SIZE,
395 len -= SHA512_BLOCK_SIZE) {
396 uint64x2_t initial_sum, sum, intermed;
397
398 uint64x2_t ab_orig = ab;
399 uint64x2_t cd_orig = cd;
400 uint64x2_t ef_orig = ef;
401 uint64x2_t gh_orig = gh;
402
403 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
404 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
405 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
406 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
407 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
408 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
409 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
410 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
411
412#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
413 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
414 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
415 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
416 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
417 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
418 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
419 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
420 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
421#endif
422
423 /* Rounds 0 and 1 */
424 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
425 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
426 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
427 gh = vsha512h2q_u64(intermed, cd, ab);
428 cd = vaddq_u64(cd, intermed);
429
430 /* Rounds 2 and 3 */
431 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
432 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
433 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
434 ef = vsha512h2q_u64(intermed, ab, gh);
435 ab = vaddq_u64(ab, intermed);
436
437 /* Rounds 4 and 5 */
438 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
439 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
440 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
441 cd = vsha512h2q_u64(intermed, gh, ef);
442 gh = vaddq_u64(gh, intermed);
443
444 /* Rounds 6 and 7 */
445 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
446 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
447 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
448 ab = vsha512h2q_u64(intermed, ef, cd);
449 ef = vaddq_u64(ef, intermed);
450
451 /* Rounds 8 and 9 */
452 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
453 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
454 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
455 gh = vsha512h2q_u64(intermed, cd, ab);
456 cd = vaddq_u64(cd, intermed);
457
458 /* Rounds 10 and 11 */
459 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
460 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
461 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
462 ef = vsha512h2q_u64(intermed, ab, gh);
463 ab = vaddq_u64(ab, intermed);
464
465 /* Rounds 12 and 13 */
466 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
467 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
468 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
469 cd = vsha512h2q_u64(intermed, gh, ef);
470 gh = vaddq_u64(gh, intermed);
471
472 /* Rounds 14 and 15 */
473 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
474 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
475 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
476 ab = vsha512h2q_u64(intermed, ef, cd);
477 ef = vaddq_u64(ef, intermed);
478
479 for (unsigned int t = 16; t < 80; t += 16) {
480 /* Rounds t and t + 1 */
481 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
482 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
483 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
484 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
485 gh = vsha512h2q_u64(intermed, cd, ab);
486 cd = vaddq_u64(cd, intermed);
487
488 /* Rounds t + 2 and t + 3 */
489 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
490 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
491 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
492 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
493 ef = vsha512h2q_u64(intermed, ab, gh);
494 ab = vaddq_u64(ab, intermed);
495
496 /* Rounds t + 4 and t + 5 */
497 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
498 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
499 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
500 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
501 cd = vsha512h2q_u64(intermed, gh, ef);
502 gh = vaddq_u64(gh, intermed);
503
504 /* Rounds t + 6 and t + 7 */
505 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
506 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
507 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
508 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
509 ab = vsha512h2q_u64(intermed, ef, cd);
510 ef = vaddq_u64(ef, intermed);
511
512 /* Rounds t + 8 and t + 9 */
513 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
514 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
515 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
516 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
517 gh = vsha512h2q_u64(intermed, cd, ab);
518 cd = vaddq_u64(cd, intermed);
519
520 /* Rounds t + 10 and t + 11 */
521 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
522 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
523 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
524 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
525 ef = vsha512h2q_u64(intermed, ab, gh);
526 ab = vaddq_u64(ab, intermed);
527
528 /* Rounds t + 12 and t + 13 */
529 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
530 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
531 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
532 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
533 cd = vsha512h2q_u64(intermed, gh, ef);
534 gh = vaddq_u64(gh, intermed);
535
536 /* Rounds t + 14 and t + 15 */
537 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
538 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
539 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
540 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
541 ab = vsha512h2q_u64(intermed, ef, cd);
542 ef = vaddq_u64(ef, intermed);
543 }
544
545 ab = vaddq_u64(ab, ab_orig);
546 cd = vaddq_u64(cd, cd_orig);
547 ef = vaddq_u64(ef, ef_orig);
548 gh = vaddq_u64(gh, gh_orig);
549 }
550
551 vst1q_u64(&ctx->state[0], ab);
552 vst1q_u64(&ctx->state[2], cd);
553 vst1q_u64(&ctx->state[4], ef);
554 vst1q_u64(&ctx->state[6], gh);
555
556 return processed;
557}
558
559#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
560/*
561 * This function is for internal use only if we are building both C and A64
562 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
563 */
564static
565#endif
566int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
567 const unsigned char data[SHA512_BLOCK_SIZE])
568{
569 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
570 SHA512_BLOCK_SIZE) ==
571 SHA512_BLOCK_SIZE) ? 0 : -1;
572}
573
Tom Van Eyckc1633172024-04-09 18:44:13 +0200574#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
575
Jens Wiklander32b31802023-10-06 16:59:46 +0200576#if defined(MBEDTLS_POP_TARGET_PRAGMA)
577#if defined(__clang__)
578#pragma clang attribute pop
579#elif defined(__GNUC__)
580#pragma GCC pop_options
581#endif
582#undef MBEDTLS_POP_TARGET_PRAGMA
583#endif
584
Jens Wiklander32b31802023-10-06 16:59:46 +0200585
586#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
587#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
588#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
589#endif
590
591
592#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
593
594#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
595/*
596 * This function is for internal use only if we are building both C and A64
597 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
598 */
599static
600#endif
601int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
602 const unsigned char data[SHA512_BLOCK_SIZE])
Jens Wiklander817466c2018-05-22 13:49:31 +0200603{
604 int i;
Jens Wiklander32b31802023-10-06 16:59:46 +0200605 struct {
Jerome Forissier79013242021-07-28 10:24:04 +0200606 uint64_t temp1, temp2, W[80];
607 uint64_t A[8];
608 } local;
Jens Wiklander817466c2018-05-22 13:49:31 +0200609
Jens Wiklander32b31802023-10-06 16:59:46 +0200610#define SHR(x, n) ((x) >> (n))
611#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200612
613#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Jens Wiklander32b31802023-10-06 16:59:46 +0200614#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Jens Wiklander817466c2018-05-22 13:49:31 +0200615
Jens Wiklander32b31802023-10-06 16:59:46 +0200616#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
617#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Jens Wiklander817466c2018-05-22 13:49:31 +0200618
Jens Wiklander32b31802023-10-06 16:59:46 +0200619#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
620#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200621
Jens Wiklander32b31802023-10-06 16:59:46 +0200622#define P(a, b, c, d, e, f, g, h, x, K) \
Jerome Forissier79013242021-07-28 10:24:04 +0200623 do \
624 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200625 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
626 local.temp2 = S2(a) + F0((a), (b), (c)); \
Jerome Forissier79013242021-07-28 10:24:04 +0200627 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Jens Wiklander32b31802023-10-06 16:59:46 +0200628 } while (0)
Jens Wiklander817466c2018-05-22 13:49:31 +0200629
Jens Wiklander32b31802023-10-06 16:59:46 +0200630 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200631 local.A[i] = ctx->state[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200632 }
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200633
634#if defined(MBEDTLS_SHA512_SMALLER)
Jens Wiklander32b31802023-10-06 16:59:46 +0200635 for (i = 0; i < 80; i++) {
636 if (i < 16) {
637 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
638 } else {
Jerome Forissier79013242021-07-28 10:24:04 +0200639 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Jens Wiklander32b31802023-10-06 16:59:46 +0200640 S0(local.W[i - 15]) + local.W[i - 16];
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200641 }
642
Jens Wiklander32b31802023-10-06 16:59:46 +0200643 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
644 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200645
Jerome Forissier79013242021-07-28 10:24:04 +0200646 local.temp1 = local.A[7]; local.A[7] = local.A[6];
647 local.A[6] = local.A[5]; local.A[5] = local.A[4];
648 local.A[4] = local.A[3]; local.A[3] = local.A[2];
649 local.A[2] = local.A[1]; local.A[1] = local.A[0];
650 local.A[0] = local.temp1;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200651 }
652#else /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander32b31802023-10-06 16:59:46 +0200653 for (i = 0; i < 16; i++) {
654 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200655 }
656
Jens Wiklander32b31802023-10-06 16:59:46 +0200657 for (; i < 80; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200658 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Jens Wiklander32b31802023-10-06 16:59:46 +0200659 S0(local.W[i - 15]) + local.W[i - 16];
Jens Wiklander817466c2018-05-22 13:49:31 +0200660 }
661
Jens Wiklander817466c2018-05-22 13:49:31 +0200662 i = 0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200663 do {
664 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
665 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
666 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
667 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
668 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
669 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
670 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
671 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
672 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
673 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
674 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
675 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
676 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
677 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
678 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
679 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
680 } while (i < 80);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200681#endif /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander817466c2018-05-22 13:49:31 +0200682
Jens Wiklander32b31802023-10-06 16:59:46 +0200683 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200684 ctx->state[i] += local.A[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200685 }
Jerome Forissier79013242021-07-28 10:24:04 +0200686
687 /* Zeroise buffers and variables to clear sensitive data from memory. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200688 mbedtls_platform_zeroize(&local, sizeof(local));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100689
Jens Wiklander32b31802023-10-06 16:59:46 +0200690 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200691}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100692
Jens Wiklander32b31802023-10-06 16:59:46 +0200693#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
694
695
696#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
697
698static size_t mbedtls_internal_sha512_process_many_c(
699 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100700{
Jens Wiklander32b31802023-10-06 16:59:46 +0200701 size_t processed = 0;
702
703 while (len >= SHA512_BLOCK_SIZE) {
704 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
705 return 0;
706 }
707
708 data += SHA512_BLOCK_SIZE;
709 len -= SHA512_BLOCK_SIZE;
710
711 processed += SHA512_BLOCK_SIZE;
712 }
713
714 return processed;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100715}
Jens Wiklander32b31802023-10-06 16:59:46 +0200716
717#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
718
719
720#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
721
722static int mbedtls_a64_crypto_sha512_has_support(void)
723{
724 static int done = 0;
725 static int supported = 0;
726
727 if (!done) {
728 supported = mbedtls_a64_crypto_sha512_determine_support();
729 done = 1;
730 }
731
732 return supported;
733}
734
735static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
736 const uint8_t *msg, size_t len)
737{
738 if (mbedtls_a64_crypto_sha512_has_support()) {
739 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
740 } else {
741 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
742 }
743}
744
745int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
746 const unsigned char data[SHA512_BLOCK_SIZE])
747{
748 if (mbedtls_a64_crypto_sha512_has_support()) {
749 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
750 } else {
751 return mbedtls_internal_sha512_process_c(ctx, data);
752 }
753}
754
755#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Jens Wiklander817466c2018-05-22 13:49:31 +0200756
757/*
758 * SHA-512 process buffer
759 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200760int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
761 const unsigned char *input,
762 size_t ilen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200763{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200764 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200765 size_t fill;
766 unsigned int left;
767
Jens Wiklander32b31802023-10-06 16:59:46 +0200768 if (ilen == 0) {
769 return 0;
770 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200771
772 left = (unsigned int) (ctx->total[0] & 0x7F);
Jens Wiklander32b31802023-10-06 16:59:46 +0200773 fill = SHA512_BLOCK_SIZE - left;
Jens Wiklander817466c2018-05-22 13:49:31 +0200774
775 ctx->total[0] += (uint64_t) ilen;
776
Jens Wiklander32b31802023-10-06 16:59:46 +0200777 if (ctx->total[0] < (uint64_t) ilen) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200778 ctx->total[1]++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200779 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200780
Jens Wiklander32b31802023-10-06 16:59:46 +0200781 if (left && ilen >= fill) {
782 memcpy((void *) (ctx->buffer + left), input, fill);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100783
Jens Wiklander32b31802023-10-06 16:59:46 +0200784 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
785 return ret;
786 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100787
Jens Wiklander817466c2018-05-22 13:49:31 +0200788 input += fill;
789 ilen -= fill;
790 left = 0;
791 }
792
Jens Wiklander32b31802023-10-06 16:59:46 +0200793 while (ilen >= SHA512_BLOCK_SIZE) {
794 size_t processed =
795 mbedtls_internal_sha512_process_many(ctx, input, ilen);
796 if (processed < SHA512_BLOCK_SIZE) {
797 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
798 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100799
Jens Wiklander32b31802023-10-06 16:59:46 +0200800 input += processed;
801 ilen -= processed;
Jens Wiklander817466c2018-05-22 13:49:31 +0200802 }
803
Jens Wiklander32b31802023-10-06 16:59:46 +0200804 if (ilen > 0) {
805 memcpy((void *) (ctx->buffer + left), input, ilen);
806 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100807
Jens Wiklander32b31802023-10-06 16:59:46 +0200808 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200809}
810
Jens Wiklander817466c2018-05-22 13:49:31 +0200811/*
812 * SHA-512 final digest
813 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200814int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
815 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +0200816{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200817 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100818 unsigned used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200819 uint64_t high, low;
Tom Van Eyckc1633172024-04-09 18:44:13 +0200820 int truncated = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200821
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100822 /*
823 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
824 */
825 used = ctx->total[0] & 0x7F;
826
827 ctx->buffer[used++] = 0x80;
828
Jens Wiklander32b31802023-10-06 16:59:46 +0200829 if (used <= 112) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100830 /* Enough room for padding + length in current block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200831 memset(ctx->buffer + used, 0, 112 - used);
832 } else {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100833 /* We'll need an extra block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200834 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100835
Jens Wiklander32b31802023-10-06 16:59:46 +0200836 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Tom Van Eyckc1633172024-04-09 18:44:13 +0200837 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200838 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100839
Jens Wiklander32b31802023-10-06 16:59:46 +0200840 memset(ctx->buffer, 0, 112);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100841 }
842
843 /*
844 * Add message length
845 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200846 high = (ctx->total[0] >> 61)
847 | (ctx->total[1] << 3);
848 low = (ctx->total[0] << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200849
Jens Wiklander32b31802023-10-06 16:59:46 +0200850 sha512_put_uint64_be(high, ctx->buffer, 112);
851 sha512_put_uint64_be(low, ctx->buffer, 120);
Jens Wiklander817466c2018-05-22 13:49:31 +0200852
Jens Wiklander32b31802023-10-06 16:59:46 +0200853 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Tom Van Eyckc1633172024-04-09 18:44:13 +0200854 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200855 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200856
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100857 /*
858 * Output final state
859 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200860 sha512_put_uint64_be(ctx->state[0], output, 0);
861 sha512_put_uint64_be(ctx->state[1], output, 8);
862 sha512_put_uint64_be(ctx->state[2], output, 16);
863 sha512_put_uint64_be(ctx->state[3], output, 24);
864 sha512_put_uint64_be(ctx->state[4], output, 32);
865 sha512_put_uint64_be(ctx->state[5], output, 40);
Jens Wiklander817466c2018-05-22 13:49:31 +0200866
Jens Wiklander32b31802023-10-06 16:59:46 +0200867#if defined(MBEDTLS_SHA384_C)
868 truncated = ctx->is384;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200869#endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200870 if (!truncated) {
871 sha512_put_uint64_be(ctx->state[6], output, 48);
872 sha512_put_uint64_be(ctx->state[7], output, 56);
Jens Wiklander817466c2018-05-22 13:49:31 +0200873 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100874
Tom Van Eyckc1633172024-04-09 18:44:13 +0200875 ret = 0;
876
877exit:
878 mbedtls_sha512_free(ctx);
879 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200880}
881
882#endif /* !MBEDTLS_SHA512_ALT */
883
884/*
885 * output = SHA-512( input buffer )
886 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200887int mbedtls_sha512(const unsigned char *input,
888 size_t ilen,
889 unsigned char *output,
890 int is384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200891{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200892 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200893 mbedtls_sha512_context ctx;
894
Jens Wiklander32b31802023-10-06 16:59:46 +0200895#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
896 if (is384 != 0 && is384 != 1) {
897 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
898 }
899#elif defined(MBEDTLS_SHA512_C)
900 if (is384 != 0) {
901 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
902 }
903#else /* defined MBEDTLS_SHA384_C only */
904 if (is384 == 0) {
905 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
906 }
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200907#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100908
Jens Wiklander32b31802023-10-06 16:59:46 +0200909 mbedtls_sha512_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100910
Jens Wiklander32b31802023-10-06 16:59:46 +0200911 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100912 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200913 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100914
Jens Wiklander32b31802023-10-06 16:59:46 +0200915 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100916 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200917 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100918
Jens Wiklander32b31802023-10-06 16:59:46 +0200919 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100920 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200921 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100922
923exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200924 mbedtls_sha512_free(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100925
Jens Wiklander32b31802023-10-06 16:59:46 +0200926 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200927}
928
929#if defined(MBEDTLS_SELF_TEST)
930
931/*
932 * FIPS-180-2 test vectors
933 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200934static const unsigned char sha_test_buf[3][113] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200935{
936 { "abc" },
Jens Wiklander32b31802023-10-06 16:59:46 +0200937 {
938 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
939 },
Jens Wiklander817466c2018-05-22 13:49:31 +0200940 { "" }
941};
942
Jens Wiklander32b31802023-10-06 16:59:46 +0200943static const size_t sha_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200944{
945 3, 112, 1000
946};
947
Jens Wiklander32b31802023-10-06 16:59:46 +0200948typedef const unsigned char (sha_test_sum_t)[64];
949
950/*
951 * SHA-384 test vectors
952 */
953#if defined(MBEDTLS_SHA384_C)
954static sha_test_sum_t sha384_test_sum[] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200955{
Jens Wiklander817466c2018-05-22 13:49:31 +0200956 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
957 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
958 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
959 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
960 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
961 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
962 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
963 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
964 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
965 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
966 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
967 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
968 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
969 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
970 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
971 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
972 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Jens Wiklander32b31802023-10-06 16:59:46 +0200973 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
974};
975#endif /* MBEDTLS_SHA384_C */
Jens Wiklander817466c2018-05-22 13:49:31 +0200976
Jens Wiklander32b31802023-10-06 16:59:46 +0200977/*
978 * SHA-512 test vectors
979 */
980#if defined(MBEDTLS_SHA512_C)
981static sha_test_sum_t sha512_test_sum[] =
982{
Jens Wiklander817466c2018-05-22 13:49:31 +0200983 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
984 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
985 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
986 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
987 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
988 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
989 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
990 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
991 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
992 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
993 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
994 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
995 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
996 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
997 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
998 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
999 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
1000 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1001 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1002 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1003 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1004 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1005 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1006 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1007};
Jens Wiklander32b31802023-10-06 16:59:46 +02001008#endif /* MBEDTLS_SHA512_C */
Jens Wiklander817466c2018-05-22 13:49:31 +02001009
Jens Wiklander32b31802023-10-06 16:59:46 +02001010static int mbedtls_sha512_common_self_test(int verbose, int is384)
Jens Wiklander817466c2018-05-22 13:49:31 +02001011{
Jens Wiklander32b31802023-10-06 16:59:46 +02001012 int i, buflen, ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02001013 unsigned char *buf;
1014 unsigned char sha512sum[64];
1015 mbedtls_sha512_context ctx;
1016
Jens Wiklander32b31802023-10-06 16:59:46 +02001017#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
1018 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
1019#elif defined(MBEDTLS_SHA512_C)
1020 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001021#else
Jens Wiklander32b31802023-10-06 16:59:46 +02001022 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001023#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001024
Jens Wiklander32b31802023-10-06 16:59:46 +02001025 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1026 if (NULL == buf) {
1027 if (verbose != 0) {
1028 mbedtls_printf("Buffer allocation failed\n");
1029 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001030
Jens Wiklander32b31802023-10-06 16:59:46 +02001031 return 1;
1032 }
1033
1034 mbedtls_sha512_init(&ctx);
1035
1036 for (i = 0; i < 3; i++) {
1037 if (verbose != 0) {
1038 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1039 }
1040
1041 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001042 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +02001043 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001044
Jens Wiklander32b31802023-10-06 16:59:46 +02001045 if (i == 2) {
1046 memset(buf, 'a', buflen = 1000);
Jens Wiklander817466c2018-05-22 13:49:31 +02001047
Jens Wiklander32b31802023-10-06 16:59:46 +02001048 for (int j = 0; j < 1000; j++) {
1049 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1050 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001051 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +02001052 }
1053 }
1054 } else {
1055 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1056 sha_test_buflen[i]);
1057 if (ret != 0) {
1058 goto fail;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001059 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001060 }
Jens Wiklander32b31802023-10-06 16:59:46 +02001061
1062 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1063 goto fail;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001064 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001065
Jens Wiklander32b31802023-10-06 16:59:46 +02001066 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001067 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001068 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +02001069 }
1070
Jens Wiklander32b31802023-10-06 16:59:46 +02001071 if (verbose != 0) {
1072 mbedtls_printf("passed\n");
1073 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001074 }
1075
Jens Wiklander32b31802023-10-06 16:59:46 +02001076 if (verbose != 0) {
1077 mbedtls_printf("\n");
1078 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001079
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001080 goto exit;
1081
1082fail:
Jens Wiklander32b31802023-10-06 16:59:46 +02001083 if (verbose != 0) {
1084 mbedtls_printf("failed\n");
1085 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001086
Jens Wiklander817466c2018-05-22 13:49:31 +02001087exit:
Jens Wiklander32b31802023-10-06 16:59:46 +02001088 mbedtls_sha512_free(&ctx);
1089 mbedtls_free(buf);
Jens Wiklander817466c2018-05-22 13:49:31 +02001090
Jens Wiklander32b31802023-10-06 16:59:46 +02001091 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02001092}
1093
Jens Wiklander32b31802023-10-06 16:59:46 +02001094#if defined(MBEDTLS_SHA512_C)
1095int mbedtls_sha512_self_test(int verbose)
1096{
1097 return mbedtls_sha512_common_self_test(verbose, 0);
1098}
1099#endif /* MBEDTLS_SHA512_C */
1100
1101#if defined(MBEDTLS_SHA384_C)
1102int mbedtls_sha384_self_test(int verbose)
1103{
1104 return mbedtls_sha512_common_self_test(verbose, 1);
1105}
1106#endif /* MBEDTLS_SHA384_C */
1107
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001108#undef ARRAY_LENGTH
1109
Jens Wiklander817466c2018-05-22 13:49:31 +02001110#endif /* MBEDTLS_SELF_TEST */
1111
Jens Wiklander32b31802023-10-06 16:59:46 +02001112#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */