blob: e7575ea7768b4a896c5b055ac4ca563ec938ec55 [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200293
294/*
295 * Round constants
296 */
297static const uint64_t K[80] =
298{
299 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
300 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
301 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
302 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
303 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
304 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
305 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
306 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
307 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
308 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
309 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
310 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
311 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
312 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
313 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
314 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
315 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
316 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
317 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
318 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
319 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
320 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
321 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
322 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
323 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
324 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
325 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
326 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
327 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
328 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
329 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
330 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
331 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
332 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
333 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
334 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
335 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
336 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
337 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
338 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
339};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000340#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200341
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000342#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
343 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
344
345#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
346# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
347# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
348#endif
349
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000350/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
351 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
352 */
353
354#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 (__clang_major__ < 13 || \
356 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000357static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
358{
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
360 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000361}
362static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
363{
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
365 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000366}
367static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
368{
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
370 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000371}
372static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
373{
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
375 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000376}
377#endif /* __clang__ etc */
378
379static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000381{
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
383 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
384 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
385 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000386
387 size_t processed = 0;
388
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 for (;
390 len >= SHA512_BLOCK_SIZE;
391 processed += SHA512_BLOCK_SIZE,
392 msg += SHA512_BLOCK_SIZE,
393 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000394 uint64x2_t initial_sum, sum, intermed;
395
396 uint64x2_t ab_orig = ab;
397 uint64x2_t cd_orig = cd;
398 uint64x2_t ef_orig = ef;
399 uint64x2_t gh_orig = gh;
400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
402 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
403 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
404 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
405 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
406 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
407 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
408 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000409
410#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
412 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
413 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
414 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
415 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
416 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
417 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
418 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000419#endif
420
421 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
423 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
424 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
425 gh = vsha512h2q_u64(intermed, cd, ab);
426 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000427
428 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
430 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
431 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
432 ef = vsha512h2q_u64(intermed, ab, gh);
433 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000434
435 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
437 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
438 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
439 cd = vsha512h2q_u64(intermed, gh, ef);
440 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000441
442 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
444 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
445 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
446 ab = vsha512h2q_u64(intermed, ef, cd);
447 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000448
449 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
451 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
452 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
453 gh = vsha512h2q_u64(intermed, cd, ab);
454 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000455
456 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
458 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
459 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
460 ef = vsha512h2q_u64(intermed, ab, gh);
461 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000462
463 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
465 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
466 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
467 cd = vsha512h2q_u64(intermed, gh, ef);
468 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000469
470 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
472 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
473 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
474 ab = vsha512h2q_u64(intermed, ef, cd);
475 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000478 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
480 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
481 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
482 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
483 gh = vsha512h2q_u64(intermed, cd, ab);
484 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000485
486 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
488 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
489 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
490 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
491 ef = vsha512h2q_u64(intermed, ab, gh);
492 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000493
494 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
496 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
497 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
498 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
499 cd = vsha512h2q_u64(intermed, gh, ef);
500 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000501
502 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
504 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
505 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
506 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
507 ab = vsha512h2q_u64(intermed, ef, cd);
508 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000509
510 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
512 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
513 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
514 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
515 gh = vsha512h2q_u64(intermed, cd, ab);
516 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000517
518 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
520 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
521 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
522 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
523 ef = vsha512h2q_u64(intermed, ab, gh);
524 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000525
526 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
528 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
529 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
530 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
531 cd = vsha512h2q_u64(intermed, gh, ef);
532 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000533
534 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
536 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
537 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
538 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
539 ab = vsha512h2q_u64(intermed, ef, cd);
540 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000541 }
542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 ab = vaddq_u64(ab, ab_orig);
544 cd = vaddq_u64(cd, cd_orig);
545 ef = vaddq_u64(ef, ef_orig);
546 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000547 }
548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 vst1q_u64(&ctx->state[0], ab);
550 vst1q_u64(&ctx->state[2], cd);
551 vst1q_u64(&ctx->state[4], ef);
552 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000555}
556
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100557#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
558/*
559 * This function is for internal use only if we are building both C and A64
560 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
561 */
562static
563#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100564int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
565 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000566{
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
568 SHA512_BLOCK_SIZE) ==
569 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000570}
571
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100572#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
573
Jerry Yu92fc5382023-02-16 11:17:11 +0800574#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800575#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800576#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800577#elif defined(__GNUC__)
578#pragma GCC pop_options
579#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800580#undef MBEDTLS_POP_TARGET_PRAGMA
581#endif
582
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000583
584#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
585#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
586#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
587#endif
588
589
590#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
591
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100592#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
593/*
594 * This function is for internal use only if we are building both C and A64
595 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
596 */
597static
598#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100599int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
600 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000601{
602 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200604 uint64_t temp1, temp2, W[80];
605 uint64_t A[8];
606 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608#define SHR(x, n) ((x) >> (n))
609#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
611#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100612#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
615#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
618#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200621 do \
622 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
624 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200625 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200629 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200631
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200632#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 for (i = 0; i < 80; i++) {
634 if (i < 16) {
635 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
636 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200637 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200639 }
640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
642 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200643
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200644 local.temp1 = local.A[7]; local.A[7] = local.A[6];
645 local.A[6] = local.A[5]; local.A[5] = local.A[4];
646 local.A[4] = local.A[3]; local.A[3] = local.A[2];
647 local.A[2] = local.A[1]; local.A[1] = local.A[0];
648 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200649 }
650#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 for (i = 0; i < 16; i++) {
652 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 }
654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200656 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000658 }
659
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 do {
662 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
663 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
664 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
665 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
666 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
667 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
668 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
669 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
670 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
671 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
672 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
673 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
674 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
675 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
676 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
677 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
678 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200679#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200682 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100684
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200685 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000689}
Jaeden Amero041039f2018-02-19 15:28:08 +0000690
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000691#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
692
693
694#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
695
696static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000698{
699 size_t processed = 0;
700
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 while (len >= SHA512_BLOCK_SIZE) {
702 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
703 return 0;
704 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000705
706 data += SHA512_BLOCK_SIZE;
707 len -= SHA512_BLOCK_SIZE;
708
709 processed += SHA512_BLOCK_SIZE;
710 }
711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000713}
714
715#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
716
717
718#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
719
Gilles Peskine449bd832023-01-11 14:50:10 +0100720static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000721{
722 static int done = 0;
723 static int supported = 0;
724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000726 supported = mbedtls_a64_crypto_sha512_determine_support();
727 done = 1;
728 }
729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000731}
732
Gilles Peskine449bd832023-01-11 14:50:10 +0100733static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
734 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000735{
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 if (mbedtls_a64_crypto_sha512_has_support()) {
737 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
738 } else {
739 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
740 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000741}
742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
744 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000745{
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 if (mbedtls_a64_crypto_sha512_has_support()) {
747 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
748 } else {
749 return mbedtls_internal_sha512_process_c(ctx, data);
750 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000751}
752
753#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000754
755/*
756 * SHA-512 process buffer
757 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
759 const unsigned char *input,
760 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000761{
Janos Follath24eed8d2019-11-22 13:21:35 +0000762 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000763 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000764 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000765
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 if (ilen == 0) {
767 return 0;
768 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000769
Paul Bakkerb8213a12011-07-11 08:16:18 +0000770 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000771 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000772
Paul Bakker5c2364c2012-10-01 14:41:15 +0000773 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000776 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 if (left && ilen >= fill) {
780 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
783 return ret;
784 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100785
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 input += fill;
787 ilen -= fill;
788 left = 0;
789 }
790
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000792 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 mbedtls_internal_sha512_process_many(ctx, input, ilen);
794 if (processed < SHA512_BLOCK_SIZE) {
795 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
796 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100797
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000798 input += processed;
799 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000800 }
801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 if (ilen > 0) {
803 memcpy((void *) (ctx->buffer + left), input, ilen);
804 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100805
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000807}
808
Paul Bakker5121ce52009-01-03 21:22:43 +0000809/*
810 * SHA-512 final digest
811 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100812int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
813 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000814{
Janos Follath24eed8d2019-11-22 13:21:35 +0000815 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200816 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000817 uint64_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100818 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000819
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200820 /*
821 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
822 */
823 used = ctx->total[0] & 0x7F;
824
825 ctx->buffer[used++] = 0x80;
826
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200828 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 memset(ctx->buffer + used, 0, 112 - used);
830 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200831 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100835 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200839 }
840
841 /*
842 * Add message length
843 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 high = (ctx->total[0] >> 61)
845 | (ctx->total[1] << 3);
846 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 sha512_put_uint64_be(high, ctx->buffer, 112);
849 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100852 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200855 /*
856 * Output final state
857 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 sha512_put_uint64_be(ctx->state[0], output, 0);
859 sha512_put_uint64_be(ctx->state[1], output, 8);
860 sha512_put_uint64_be(ctx->state[2], output, 16);
861 sha512_put_uint64_be(ctx->state[3], output, 24);
862 sha512_put_uint64_be(ctx->state[4], output, 32);
863 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000864
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200865#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100866 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200867#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 if (!truncated) {
869 sha512_put_uint64_be(ctx->state[6], output, 48);
870 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000871 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100872
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100873 ret = 0;
874
875exit:
876 mbedtls_sha512_free(ctx);
877 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000878}
879
880/*
881 * output = SHA-512( input buffer )
882 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100883int mbedtls_sha512(const unsigned char *input,
884 size_t ilen,
885 unsigned char *output,
886 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000887{
Janos Follath24eed8d2019-11-22 13:21:35 +0000888 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Valerio Setti43363f52022-12-14 08:53:23 +0100891#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100893 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 }
Valerio Setti43363f52022-12-14 08:53:23 +0100895#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100897 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 }
Valerio Setti43363f52022-12-14 08:53:23 +0100899#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100901 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100903#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000904
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100908 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100912 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100914
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100916 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100918
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100919exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000923}
924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
927/*
928 * FIPS-180-2 test vectors
929 */
Valerio Setti43363f52022-12-14 08:53:23 +0100930static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000931{
932 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 {
934 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
935 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000936 { "" }
937};
938
Valerio Setti43363f52022-12-14 08:53:23 +0100939static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000940{
941 3, 112, 1000
942};
943
Valerio Setti43363f52022-12-14 08:53:23 +0100944typedef const unsigned char (sha_test_sum_t)[64];
945
946/*
947 * SHA-384 test vectors
948 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200949#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100950static sha_test_sum_t sha384_test_sum[] =
951{
Paul Bakker5121ce52009-01-03 21:22:43 +0000952 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
953 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
954 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
955 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
956 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
957 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
958 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
959 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
960 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
961 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
962 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
963 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
964 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
965 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
966 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
967 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
968 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100969 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
970};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200971#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000972
Valerio Setti43363f52022-12-14 08:53:23 +0100973/*
974 * SHA-512 test vectors
975 */
976#if defined(MBEDTLS_SHA512_C)
977static sha_test_sum_t sha512_test_sum[] =
978{
Paul Bakker5121ce52009-01-03 21:22:43 +0000979 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
980 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
981 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
982 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
983 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
984 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
985 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
986 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
987 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
988 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
989 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
990 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
991 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
992 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
993 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
994 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
995 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
996 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
997 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
998 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
999 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1000 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1001 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1002 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1003};
Valerio Setti43363f52022-12-14 08:53:23 +01001004#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001007{
Valerio Setti43363f52022-12-14 08:53:23 +01001008 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001009 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001010 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001011 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001012
Valerio Setti43363f52022-12-14 08:53:23 +01001013#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001015#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001017#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001019#endif
1020
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1022 if (NULL == buf) {
1023 if (verbose != 0) {
1024 mbedtls_printf("Buffer allocation failed\n");
1025 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001028 }
1029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001031
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 for (i = 0; i < 3; i++) {
1033 if (verbose != 0) {
1034 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1035 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001036
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001038 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 if (i == 2) {
1042 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001043
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 for (int j = 0; j < 1000; j++) {
1045 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1046 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001047 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 }
1049 }
1050 } else {
1051 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1052 sha_test_buflen[i]);
1053 if (ret != 0) {
1054 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001055 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001056 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001057
1058 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1059 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001060 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001063 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001064 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001065 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001066
Gilles Peskine449bd832023-01-11 14:50:10 +01001067 if (verbose != 0) {
1068 mbedtls_printf("passed\n");
1069 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001070 }
1071
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 if (verbose != 0) {
1073 mbedtls_printf("\n");
1074 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001075
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001076 goto exit;
1077
1078fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 if (verbose != 0) {
1080 mbedtls_printf("failed\n");
1081 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001082
Paul Bakker5b4af392014-06-26 12:09:34 +02001083exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 mbedtls_sha512_free(&ctx);
1085 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001086
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001088}
1089
Valerio Setti898e7a32022-12-14 08:55:53 +01001090#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001091int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001092{
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001094}
Valerio Setti898e7a32022-12-14 08:55:53 +01001095#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001096
Valerio Setti898e7a32022-12-14 08:55:53 +01001097#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001098int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001099{
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001101}
Valerio Setti898e7a32022-12-14 08:55:53 +01001102#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001103
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001104#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001107
Valerio Setti43363f52022-12-14 08:53:23 +01001108#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */