blob: 52b4f62a9debb3d0ec032904270127c04bec6722 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
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
Jerry Yua135dee2023-02-16 16:56:22 +080013#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
Jerry Yu6f86c192023-03-13 11:03:40 +080014 defined(__clang__) && __clang_major__ >= 7
Jerry Yua135dee2023-02-16 16:56:22 +080015/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
16 *
Jerry Yufc2e1282023-02-27 11:16:56 +080017 * 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.
Jerry Yu4d786a72023-02-22 11:01:07 +080021 *
Dave Rodgmana0f10da2023-09-05 11:43:17 +010022 * `arm_neon.h` is included by common.h, so we put these defines
Jerry Yufc2e1282023-02-27 11:16:56 +080023 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080024 */
25#define __ARM_FEATURE_SHA512 1
Dave Rodgmandb6ab242023-03-14 16:03:57 +000026#define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG
Jerry Yu490bf082023-03-06 15:21:44 +080027#endif
Jerry Yua135dee2023-02-16 16:56:22 +080028
Gilles Peskinedb09ef62020-06-03 01:43:33 +020029#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000030
Valerio Setti43363f52022-12-14 08:53:23 +010031#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000037#if defined(_MSC_VER) || defined(__WATCOMC__)
38 #define UL64(x) x##ui64
39#else
40 #define UL64(x) x##ULL
41#endif
42
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <string.h>
44
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000047#if defined(__aarch64__)
48# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010049 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080050/* *INDENT-OFF* */
Dave Rodgmana0f10da2023-09-05 11:43:17 +010051# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
Jerry Yu6b00f5a2023-05-04 16:30:21 +080052# error "Target does not support NEON instructions"
53# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080054/*
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 */
Dave Rodgmandb6ab242023-03-14 16:03:57 +000068# if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080069 /* Test Clang first, as it defines __GNUC__ */
Jerry Yu22a4d3e2023-04-28 17:43:40 +080070# if defined(__ARMCOMPILER_VERSION)
71# if __ARMCOMPILER_VERSION < 6090000
Jerry Yu8e96e782023-05-04 16:37:30 +080072# error "A more recent armclang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yub1d06bb2023-05-05 14:05:07 +080073# elif __ARMCOMPILER_VERSION == 6090000
74# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
75# else
Jerry Yu22a4d3e2023-04-28 17:43:40 +080076# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
77# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yub1d06bb2023-05-05 14:05:07 +080078# endif
Jerry Yu22a4d3e2023-04-28 17:43:40 +080079# elif defined(__clang__)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080080# if __clang_major__ < 7
81# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080082# else
Jerry Yu64e5d4a2023-02-15 11:46:57 +080083# 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
Jerry Yu2f2c0492023-02-16 14:24:46 +080090# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080091# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +080092# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080093# endif
94# else
95# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
96# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080097# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080098/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000099# endif
100# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
101# if defined(__unix__)
102# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100103/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000104# include <sys/auxv.h>
Dave Rodgmandae21d32024-01-30 15:31:42 +0000105# 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
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000113# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100114/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000115# include <signal.h>
116# endif
117# endif
Dave Rodgman0a487172023-09-15 11:52:06 +0100118#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000119# 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)
Gilles Peskine449bd832023-01-11 14:50:10 +0100129static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000130{
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000132}
133#elif defined(__APPLE__)
134#include <sys/types.h>
135#include <sys/sysctl.h>
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000138{
139 int value = 0;
140 size_t value_len = sizeof(value);
141
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
143 NULL, 0);
144 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000145}
Dave Rodgman0a487172023-09-15 11:52:06 +0100146#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000147/*
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
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000162static jmp_buf return_from_sigill;
163
164/*
165 * A64 SHA512 support detection via SIGILL
166 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100167static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000168{
169 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000171}
172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000174{
175 struct sigaction old_action, new_action;
176
177 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 if (sigprocmask(0, NULL, &old_mask)) {
179 return 0;
180 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000183 new_action.sa_flags = 0;
184 new_action.sa_handler = sigill_handler;
185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000187
188 static int ret = 0;
189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000191 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000193 ret = 1;
194 }
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 sigaction(SIGILL, &old_action, NULL);
197 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000200}
201#else
202#warning "No mechanism to detect A64_CRYPTO found, using C code only"
203#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
204#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
205
206#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
207
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000208#define SHA512_BLOCK_SIZE 128
209
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200210#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100211static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200212{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100213 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200214}
215#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100216#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200217#endif /* MBEDTLS_SHA512_SMALLER */
218
Gilles Peskine449bd832023-01-11 14:50:10 +0100219void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200220{
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200222}
223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200225{
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200227 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200231}
232
Gilles Peskine449bd832023-01-11 14:50:10 +0100233void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
234 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200235{
236 *dst = *src;
237}
238
Paul Bakker5121ce52009-01-03 21:22:43 +0000239/*
240 * SHA-512 context setup
241 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100242int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000243{
Valerio Setti43363f52022-12-14 08:53:23 +0100244#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100246 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 }
Valerio Setti43363f52022-12-14 08:53:23 +0100248#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100250 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 }
Valerio Setti43363f52022-12-14 08:53:23 +0100252#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100254 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100256#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000257
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 ctx->total[0] = 0;
259 ctx->total[1] = 0;
260
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100262#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000263 ctx->state[0] = UL64(0x6A09E667F3BCC908);
264 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
265 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
266 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
267 ctx->state[4] = UL64(0x510E527FADE682D1);
268 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
269 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
270 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100271#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100273#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000274 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
275 ctx->state[1] = UL64(0x629A292A367CD507);
276 ctx->state[2] = UL64(0x9159015A3070DD17);
277 ctx->state[3] = UL64(0x152FECD8F70E5939);
278 ctx->state[4] = UL64(0x67332667FFC00B31);
279 ctx->state[5] = UL64(0x8EB44A8768581511);
280 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
281 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200282#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 }
284
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200285#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000286 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200287#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000290}
291
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200292/*
293 * Round constants
294 */
295static const uint64_t K[80] =
296{
297 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
298 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
299 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
300 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
301 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
302 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
303 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
304 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
305 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
306 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
307 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
308 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
309 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
310 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
311 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
312 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
313 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
314 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
315 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
316 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
317 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
318 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
319 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
320 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
321 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
322 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
323 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
324 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
325 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
326 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
327 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
328 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
329 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
330 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
331 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
332 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
333 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
334 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
335 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
336 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
337};
338
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000339#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
340 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
341
342#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
343# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
344# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
345#endif
346
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000347/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
348 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
349 */
350
351#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 (__clang_major__ < 13 || \
353 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000354static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
355{
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
357 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000358}
359static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
360{
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
362 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000363}
364static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
365{
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
367 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000368}
369static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
370{
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
372 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000373}
374#endif /* __clang__ etc */
375
376static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000378{
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
380 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
381 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
382 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000383
384 size_t processed = 0;
385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 for (;
387 len >= SHA512_BLOCK_SIZE;
388 processed += SHA512_BLOCK_SIZE,
389 msg += SHA512_BLOCK_SIZE,
390 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000391 uint64x2_t initial_sum, sum, intermed;
392
393 uint64x2_t ab_orig = ab;
394 uint64x2_t cd_orig = cd;
395 uint64x2_t ef_orig = ef;
396 uint64x2_t gh_orig = gh;
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
399 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
400 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
401 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
402 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
403 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
404 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
405 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000406
407#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
409 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
410 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
411 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
412 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
413 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
414 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
415 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000416#endif
417
418 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
420 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
421 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
422 gh = vsha512h2q_u64(intermed, cd, ab);
423 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000424
425 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
427 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
428 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
429 ef = vsha512h2q_u64(intermed, ab, gh);
430 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000431
432 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
434 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
435 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
436 cd = vsha512h2q_u64(intermed, gh, ef);
437 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000438
439 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
441 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
442 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
443 ab = vsha512h2q_u64(intermed, ef, cd);
444 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000445
446 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
448 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
449 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
450 gh = vsha512h2q_u64(intermed, cd, ab);
451 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000452
453 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
455 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
456 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
457 ef = vsha512h2q_u64(intermed, ab, gh);
458 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000459
460 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
462 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
463 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
464 cd = vsha512h2q_u64(intermed, gh, ef);
465 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000466
467 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
469 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
470 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
471 ab = vsha512h2q_u64(intermed, ef, cd);
472 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000475 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
477 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
478 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
479 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
480 gh = vsha512h2q_u64(intermed, cd, ab);
481 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000482
483 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
485 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
486 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
487 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
488 ef = vsha512h2q_u64(intermed, ab, gh);
489 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000490
491 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
493 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
494 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
495 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
496 cd = vsha512h2q_u64(intermed, gh, ef);
497 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000498
499 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
501 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
502 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
503 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
504 ab = vsha512h2q_u64(intermed, ef, cd);
505 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000506
507 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
509 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
510 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
511 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
512 gh = vsha512h2q_u64(intermed, cd, ab);
513 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000514
515 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
517 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
518 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
519 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
520 ef = vsha512h2q_u64(intermed, ab, gh);
521 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000522
523 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
525 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
526 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
527 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
528 cd = vsha512h2q_u64(intermed, gh, ef);
529 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000530
531 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
533 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
534 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
535 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
536 ab = vsha512h2q_u64(intermed, ef, cd);
537 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000538 }
539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 ab = vaddq_u64(ab, ab_orig);
541 cd = vaddq_u64(cd, cd_orig);
542 ef = vaddq_u64(ef, ef_orig);
543 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000544 }
545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 vst1q_u64(&ctx->state[0], ab);
547 vst1q_u64(&ctx->state[2], cd);
548 vst1q_u64(&ctx->state[4], ef);
549 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000552}
553
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100554#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
555/*
556 * This function is for internal use only if we are building both C and A64
557 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
558 */
559static
560#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100561int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
562 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000563{
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
565 SHA512_BLOCK_SIZE) ==
566 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000567}
568
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100569#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
570
Jerry Yu92fc5382023-02-16 11:17:11 +0800571#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800572#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800573#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800574#elif defined(__GNUC__)
575#pragma GCC pop_options
576#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800577#undef MBEDTLS_POP_TARGET_PRAGMA
578#endif
579
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000580
581#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
582#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
583#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
584#endif
585
586
Thomas Daubney3ab1b2d2024-07-16 17:34:31 +0100587#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000588
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100589#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
590/*
591 * This function is for internal use only if we are building both C and A64
592 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
593 */
594static
595#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100596int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
597 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000598{
599 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200601 uint64_t temp1, temp2, W[80];
602 uint64_t A[8];
603 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605#define SHR(x, n) ((x) >> (n))
606#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
608#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100609#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
612#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
615#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200618 do \
619 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
621 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200622 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200626 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200628
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200629#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 for (i = 0; i < 80; i++) {
631 if (i < 16) {
632 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
633 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200634 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200636 }
637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
639 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200640
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200641 local.temp1 = local.A[7]; local.A[7] = local.A[6];
642 local.A[6] = local.A[5]; local.A[5] = local.A[4];
643 local.A[4] = local.A[3]; local.A[3] = local.A[2];
644 local.A[2] = local.A[1]; local.A[1] = local.A[0];
645 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200646 }
647#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 for (i = 0; i < 16; i++) {
649 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000650 }
651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200653 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000655 }
656
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 do {
659 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
660 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
661 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
662 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
663 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
664 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
665 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
666 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
667 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
668 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
669 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
670 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
671 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
672 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
673 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
674 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
675 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200676#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200679 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100681
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200682 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000686}
Jaeden Amero041039f2018-02-19 15:28:08 +0000687
Thomas Daubney3ab1b2d2024-07-16 17:34:31 +0100688#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000689
690
691#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
692
693static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000695{
696 size_t processed = 0;
697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 while (len >= SHA512_BLOCK_SIZE) {
699 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
700 return 0;
701 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000702
703 data += SHA512_BLOCK_SIZE;
704 len -= SHA512_BLOCK_SIZE;
705
706 processed += SHA512_BLOCK_SIZE;
707 }
708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000710}
711
712#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
713
714
715#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000718{
719 static int done = 0;
720 static int supported = 0;
721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000723 supported = mbedtls_a64_crypto_sha512_determine_support();
724 done = 1;
725 }
726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000728}
729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
731 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000732{
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 if (mbedtls_a64_crypto_sha512_has_support()) {
734 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
735 } else {
736 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
737 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000738}
739
Gilles Peskine449bd832023-01-11 14:50:10 +0100740int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
741 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000742{
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 if (mbedtls_a64_crypto_sha512_has_support()) {
744 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
745 } else {
746 return mbedtls_internal_sha512_process_c(ctx, data);
747 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000748}
749
750#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
752/*
753 * SHA-512 process buffer
754 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100755int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
756 const unsigned char *input,
757 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000758{
Janos Follath24eed8d2019-11-22 13:21:35 +0000759 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000760 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000761 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000762
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 if (ilen == 0) {
764 return 0;
765 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000766
Paul Bakkerb8213a12011-07-11 08:16:18 +0000767 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000768 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000769
Paul Bakker5c2364c2012-10-01 14:41:15 +0000770 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 if (left && ilen >= fill) {
777 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
780 return ret;
781 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100782
Paul Bakker5121ce52009-01-03 21:22:43 +0000783 input += fill;
784 ilen -= fill;
785 left = 0;
786 }
787
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000789 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 mbedtls_internal_sha512_process_many(ctx, input, ilen);
791 if (processed < SHA512_BLOCK_SIZE) {
792 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
793 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100794
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000795 input += processed;
796 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 }
798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 if (ilen > 0) {
800 memcpy((void *) (ctx->buffer + left), input, ilen);
801 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000804}
805
Paul Bakker5121ce52009-01-03 21:22:43 +0000806/*
807 * SHA-512 final digest
808 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100809int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
810 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000811{
Janos Follath24eed8d2019-11-22 13:21:35 +0000812 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200813 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000814 uint64_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100815 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000816
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200817 /*
818 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
819 */
820 used = ctx->total[0] & 0x7F;
821
822 ctx->buffer[used++] = 0x80;
823
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200825 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 memset(ctx->buffer + used, 0, 112 - used);
827 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200828 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100832 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200834
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200836 }
837
838 /*
839 * Add message length
840 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 high = (ctx->total[0] >> 61)
842 | (ctx->total[1] << 3);
843 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 sha512_put_uint64_be(high, ctx->buffer, 112);
846 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100849 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000851
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200852 /*
853 * Output final state
854 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 sha512_put_uint64_be(ctx->state[0], output, 0);
856 sha512_put_uint64_be(ctx->state[1], output, 8);
857 sha512_put_uint64_be(ctx->state[2], output, 16);
858 sha512_put_uint64_be(ctx->state[3], output, 24);
859 sha512_put_uint64_be(ctx->state[4], output, 32);
860 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200862#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100863 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200864#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 if (!truncated) {
866 sha512_put_uint64_be(ctx->state[6], output, 48);
867 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000868 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100869
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100870 ret = 0;
871
872exit:
873 mbedtls_sha512_free(ctx);
874 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000875}
876
877/*
878 * output = SHA-512( input buffer )
879 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100880int mbedtls_sha512(const unsigned char *input,
881 size_t ilen,
882 unsigned char *output,
883 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000884{
Janos Follath24eed8d2019-11-22 13:21:35 +0000885 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200886 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000887
Valerio Setti43363f52022-12-14 08:53:23 +0100888#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100890 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 }
Valerio Setti43363f52022-12-14 08:53:23 +0100892#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100894 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 }
Valerio Setti43363f52022-12-14 08:53:23 +0100896#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100898 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100900#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100905 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100909 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100913 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100915
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100916exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000920}
921
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
924/*
925 * FIPS-180-2 test vectors
926 */
Valerio Setti43363f52022-12-14 08:53:23 +0100927static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000928{
929 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 {
931 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
932 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 { "" }
934};
935
Valerio Setti43363f52022-12-14 08:53:23 +0100936static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000937{
938 3, 112, 1000
939};
940
Valerio Setti43363f52022-12-14 08:53:23 +0100941typedef const unsigned char (sha_test_sum_t)[64];
942
943/*
944 * SHA-384 test vectors
945 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200946#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100947static sha_test_sum_t sha384_test_sum[] =
948{
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
950 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
951 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
952 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
953 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
954 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
955 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
956 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
957 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
958 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
959 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
960 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
961 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
962 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
963 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
964 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
965 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100966 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
967};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200968#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000969
Valerio Setti43363f52022-12-14 08:53:23 +0100970/*
971 * SHA-512 test vectors
972 */
973#if defined(MBEDTLS_SHA512_C)
974static sha_test_sum_t sha512_test_sum[] =
975{
Paul Bakker5121ce52009-01-03 21:22:43 +0000976 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
977 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
978 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
979 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
980 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
981 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
982 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
983 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
984 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
985 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
986 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
987 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
988 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
989 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
990 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
991 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
992 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
993 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
994 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
995 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
996 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
997 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
998 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
999 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1000};
Valerio Setti43363f52022-12-14 08:53:23 +01001001#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001004{
Valerio Setti43363f52022-12-14 08:53:23 +01001005 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001006 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001007 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001008 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
Valerio Setti43363f52022-12-14 08:53:23 +01001010#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001012#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001014#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001016#endif
1017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1019 if (NULL == buf) {
1020 if (verbose != 0) {
1021 mbedtls_printf("Buffer allocation failed\n");
1022 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001023
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001025 }
1026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001028
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 for (i = 0; i < 3; i++) {
1030 if (verbose != 0) {
1031 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1032 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001035 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 if (i == 2) {
1039 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 for (int j = 0; j < 1000; j++) {
1042 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1043 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001044 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 }
1046 }
1047 } else {
1048 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1049 sha_test_buflen[i]);
1050 if (ret != 0) {
1051 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001052 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001053 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001054
1055 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1056 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001057 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001058
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001060 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001061 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001062 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001063
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 if (verbose != 0) {
1065 mbedtls_printf("passed\n");
1066 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001067 }
1068
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 if (verbose != 0) {
1070 mbedtls_printf("\n");
1071 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001072
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001073 goto exit;
1074
1075fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 if (verbose != 0) {
1077 mbedtls_printf("failed\n");
1078 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001079
Paul Bakker5b4af392014-06-26 12:09:34 +02001080exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 mbedtls_sha512_free(&ctx);
1082 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001083
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001085}
1086
Valerio Setti898e7a32022-12-14 08:55:53 +01001087#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001088int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001089{
Gilles Peskine449bd832023-01-11 14:50:10 +01001090 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001091}
Valerio Setti898e7a32022-12-14 08:55:53 +01001092#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001093
Valerio Setti898e7a32022-12-14 08:55:53 +01001094#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001095int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001096{
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001098}
Valerio Setti898e7a32022-12-14 08:55:53 +01001099#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001100
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001101#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001104
Valerio Setti43363f52022-12-14 08:53:23 +01001105#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */