blob: 601125445cff7f223e062235a0755d79d2c96f5e [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>
105# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100106/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000107# include <signal.h>
108# endif
109# endif
Dave Rodgman0a487172023-09-15 11:52:06 +0100110#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000111# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
112# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
113#endif
114
115#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
116/*
117 * Capability detection code comes early, so we can disable
118 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
119 */
120#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100121static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000122{
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000124}
125#elif defined(__APPLE__)
126#include <sys/types.h>
127#include <sys/sysctl.h>
128
Gilles Peskine449bd832023-01-11 14:50:10 +0100129static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000130{
131 int value = 0;
132 size_t value_len = sizeof(value);
133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
135 NULL, 0);
136 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000137}
Dave Rodgman0a487172023-09-15 11:52:06 +0100138#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000139/*
140 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
141 * available to pass to IsProcessorFeaturePresent() to check for
142 * SHA-512 support. So we fall back to the C code only.
143 */
144#if defined(_MSC_VER)
145#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
146#else
147#warning "No mechanism to detect A64_CRYPTO found, using C code only"
148#endif
149#elif defined(__unix__) && defined(SIG_SETMASK)
150/* Detection with SIGILL, setjmp() and longjmp() */
151#include <signal.h>
152#include <setjmp.h>
153
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000154static jmp_buf return_from_sigill;
155
156/*
157 * A64 SHA512 support detection via SIGILL
158 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100159static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000160{
161 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000163}
164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000166{
167 struct sigaction old_action, new_action;
168
169 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 if (sigprocmask(0, NULL, &old_mask)) {
171 return 0;
172 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000175 new_action.sa_flags = 0;
176 new_action.sa_handler = sigill_handler;
177
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000179
180 static int ret = 0;
181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000183 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000185 ret = 1;
186 }
187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 sigaction(SIGILL, &old_action, NULL);
189 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000192}
193#else
194#warning "No mechanism to detect A64_CRYPTO found, using C code only"
195#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
196#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
197
198#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
199
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200200#if !defined(MBEDTLS_SHA512_ALT)
201
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000202#define SHA512_BLOCK_SIZE 128
203
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200204#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100205static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200206{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100207 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200208}
209#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100210#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200211#endif /* MBEDTLS_SHA512_SMALLER */
212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200214{
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200216}
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200219{
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200221 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200225}
226
Gilles Peskine449bd832023-01-11 14:50:10 +0100227void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
228 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200229{
230 *dst = *src;
231}
232
Paul Bakker5121ce52009-01-03 21:22:43 +0000233/*
234 * SHA-512 context setup
235 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100236int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000237{
Valerio Setti43363f52022-12-14 08:53:23 +0100238#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100240 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 }
Valerio Setti43363f52022-12-14 08:53:23 +0100242#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100244 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 }
Valerio Setti43363f52022-12-14 08:53:23 +0100246#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100248 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100250#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000251
Paul Bakker5121ce52009-01-03 21:22:43 +0000252 ctx->total[0] = 0;
253 ctx->total[1] = 0;
254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100256#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000257 ctx->state[0] = UL64(0x6A09E667F3BCC908);
258 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
259 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
260 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
261 ctx->state[4] = UL64(0x510E527FADE682D1);
262 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
263 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
264 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100265#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100267#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000268 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
269 ctx->state[1] = UL64(0x629A292A367CD507);
270 ctx->state[2] = UL64(0x9159015A3070DD17);
271 ctx->state[3] = UL64(0x152FECD8F70E5939);
272 ctx->state[4] = UL64(0x67332667FFC00B31);
273 ctx->state[5] = UL64(0x8EB44A8768581511);
274 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
275 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200276#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 }
278
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200279#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200281#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000284}
285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200287
288/*
289 * Round constants
290 */
291static const uint64_t K[80] =
292{
293 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
294 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
295 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
296 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
297 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
298 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
299 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
300 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
301 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
302 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
303 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
304 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
305 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
306 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
307 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
308 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
309 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
310 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
311 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
312 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
313 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
314 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
315 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
316 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
317 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
318 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
319 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
320 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
321 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
322 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
323 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
324 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
325 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
326 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
327 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
328 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
329 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
330 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
331 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
332 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
333};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000334#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200335
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000336#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
337 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
338
339#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
340# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
341# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
342#endif
343
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000344/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
345 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
346 */
347
348#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 (__clang_major__ < 13 || \
350 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000351static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
352{
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
354 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000355}
356static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
357{
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
359 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000360}
361static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
362{
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
364 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000365}
366static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
367{
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
369 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000370}
371#endif /* __clang__ etc */
372
373static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000375{
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
377 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
378 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
379 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000380
381 size_t processed = 0;
382
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 for (;
384 len >= SHA512_BLOCK_SIZE;
385 processed += SHA512_BLOCK_SIZE,
386 msg += SHA512_BLOCK_SIZE,
387 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000388 uint64x2_t initial_sum, sum, intermed;
389
390 uint64x2_t ab_orig = ab;
391 uint64x2_t cd_orig = cd;
392 uint64x2_t ef_orig = ef;
393 uint64x2_t gh_orig = gh;
394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
396 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
397 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
398 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
399 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
400 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
401 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
402 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000403
404#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
406 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
407 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
408 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
409 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
410 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
411 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
412 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000413#endif
414
415 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
417 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
418 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
419 gh = vsha512h2q_u64(intermed, cd, ab);
420 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000421
422 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
424 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
425 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
426 ef = vsha512h2q_u64(intermed, ab, gh);
427 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000428
429 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
431 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
432 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
433 cd = vsha512h2q_u64(intermed, gh, ef);
434 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000435
436 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
438 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
439 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
440 ab = vsha512h2q_u64(intermed, ef, cd);
441 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000442
443 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
445 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
446 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
447 gh = vsha512h2q_u64(intermed, cd, ab);
448 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000449
450 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
452 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
453 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
454 ef = vsha512h2q_u64(intermed, ab, gh);
455 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000456
457 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
459 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
460 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
461 cd = vsha512h2q_u64(intermed, gh, ef);
462 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000463
464 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
466 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
467 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
468 ab = vsha512h2q_u64(intermed, ef, cd);
469 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000472 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
474 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
475 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
476 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
477 gh = vsha512h2q_u64(intermed, cd, ab);
478 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000479
480 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
482 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
483 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
484 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
485 ef = vsha512h2q_u64(intermed, ab, gh);
486 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000487
488 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
490 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
491 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
492 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
493 cd = vsha512h2q_u64(intermed, gh, ef);
494 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000495
496 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
498 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
499 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
500 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
501 ab = vsha512h2q_u64(intermed, ef, cd);
502 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000503
504 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
506 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
507 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
508 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
509 gh = vsha512h2q_u64(intermed, cd, ab);
510 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000511
512 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
514 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
515 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
516 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
517 ef = vsha512h2q_u64(intermed, ab, gh);
518 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000519
520 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
522 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
523 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
524 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
525 cd = vsha512h2q_u64(intermed, gh, ef);
526 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000527
528 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
530 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
531 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
532 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
533 ab = vsha512h2q_u64(intermed, ef, cd);
534 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000535 }
536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 ab = vaddq_u64(ab, ab_orig);
538 cd = vaddq_u64(cd, cd_orig);
539 ef = vaddq_u64(ef, ef_orig);
540 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000541 }
542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 vst1q_u64(&ctx->state[0], ab);
544 vst1q_u64(&ctx->state[2], cd);
545 vst1q_u64(&ctx->state[4], ef);
546 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000549}
550
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100551#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
552/*
553 * This function is for internal use only if we are building both C and A64
554 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
555 */
556static
557#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100558int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
559 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000560{
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
562 SHA512_BLOCK_SIZE) ==
563 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000564}
565
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100566#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
567
Jerry Yu92fc5382023-02-16 11:17:11 +0800568#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800569#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800570#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800571#elif defined(__GNUC__)
572#pragma GCC pop_options
573#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800574#undef MBEDTLS_POP_TARGET_PRAGMA
575#endif
576
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000577
578#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
579#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
580#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
581#endif
582
583
584#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
585
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100586#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
587/*
588 * This function is for internal use only if we are building both C and A64
589 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
590 */
591static
592#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100593int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
594 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000595{
596 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200598 uint64_t temp1, temp2, W[80];
599 uint64_t A[8];
600 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602#define SHR(x, n) ((x) >> (n))
603#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100606#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
609#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
612#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200615 do \
616 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
618 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200619 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200623 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200625
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200626#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 for (i = 0; i < 80; i++) {
628 if (i < 16) {
629 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
630 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200631 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200633 }
634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
636 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200637
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200638 local.temp1 = local.A[7]; local.A[7] = local.A[6];
639 local.A[6] = local.A[5]; local.A[5] = local.A[4];
640 local.A[4] = local.A[3]; local.A[3] = local.A[2];
641 local.A[2] = local.A[1]; local.A[1] = local.A[0];
642 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200643 }
644#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 for (i = 0; i < 16; i++) {
646 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000647 }
648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200650 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 }
653
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 do {
656 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
657 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
658 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
659 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
660 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
661 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
662 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
663 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
664 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
665 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
666 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
667 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
668 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
669 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
670 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
671 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
672 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200673#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200676 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100678
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200679 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000683}
Jaeden Amero041039f2018-02-19 15:28:08 +0000684
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000685#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
686
687
688#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
689
690static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000692{
693 size_t processed = 0;
694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 while (len >= SHA512_BLOCK_SIZE) {
696 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
697 return 0;
698 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000699
700 data += SHA512_BLOCK_SIZE;
701 len -= SHA512_BLOCK_SIZE;
702
703 processed += SHA512_BLOCK_SIZE;
704 }
705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000707}
708
709#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
710
711
712#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000715{
716 static int done = 0;
717 static int supported = 0;
718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000720 supported = mbedtls_a64_crypto_sha512_determine_support();
721 done = 1;
722 }
723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000725}
726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
728 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000729{
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (mbedtls_a64_crypto_sha512_has_support()) {
731 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
732 } else {
733 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
734 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000735}
736
Gilles Peskine449bd832023-01-11 14:50:10 +0100737int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
738 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000739{
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 if (mbedtls_a64_crypto_sha512_has_support()) {
741 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
742 } else {
743 return mbedtls_internal_sha512_process_c(ctx, data);
744 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000745}
746
747#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
749/*
750 * SHA-512 process buffer
751 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100752int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
753 const unsigned char *input,
754 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000755{
Janos Follath24eed8d2019-11-22 13:21:35 +0000756 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000757 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000758 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if (ilen == 0) {
761 return 0;
762 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000763
Paul Bakkerb8213a12011-07-11 08:16:18 +0000764 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000765 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000766
Paul Bakker5c2364c2012-10-01 14:41:15 +0000767 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000770 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 if (left && ilen >= fill) {
774 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
777 return ret;
778 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100779
Paul Bakker5121ce52009-01-03 21:22:43 +0000780 input += fill;
781 ilen -= fill;
782 left = 0;
783 }
784
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000786 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 mbedtls_internal_sha512_process_many(ctx, input, ilen);
788 if (processed < SHA512_BLOCK_SIZE) {
789 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
790 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100791
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000792 input += processed;
793 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 }
795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 if (ilen > 0) {
797 memcpy((void *) (ctx->buffer + left), input, ilen);
798 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100799
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000801}
802
Paul Bakker5121ce52009-01-03 21:22:43 +0000803/*
804 * SHA-512 final digest
805 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100806int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
807 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000808{
Janos Follath24eed8d2019-11-22 13:21:35 +0000809 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200810 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000811 uint64_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100812 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200814 /*
815 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
816 */
817 used = ctx->total[0] & 0x7F;
818
819 ctx->buffer[used++] = 0x80;
820
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200822 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 memset(ctx->buffer + used, 0, 112 - used);
824 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200825 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100829 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200833 }
834
835 /*
836 * Add message length
837 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 high = (ctx->total[0] >> 61)
839 | (ctx->total[1] << 3);
840 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 sha512_put_uint64_be(high, ctx->buffer, 112);
843 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100846 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000848
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200849 /*
850 * Output final state
851 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 sha512_put_uint64_be(ctx->state[0], output, 0);
853 sha512_put_uint64_be(ctx->state[1], output, 8);
854 sha512_put_uint64_be(ctx->state[2], output, 16);
855 sha512_put_uint64_be(ctx->state[3], output, 24);
856 sha512_put_uint64_be(ctx->state[4], output, 32);
857 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000858
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200859#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100860 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200861#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 if (!truncated) {
863 sha512_put_uint64_be(ctx->state[6], output, 48);
864 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000865 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100866
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100867 ret = 0;
868
869exit:
870 mbedtls_sha512_free(ctx);
871 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000872}
873
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200875
Paul Bakker5121ce52009-01-03 21:22:43 +0000876/*
877 * output = SHA-512( input buffer )
878 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100879int mbedtls_sha512(const unsigned char *input,
880 size_t ilen,
881 unsigned char *output,
882 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000883{
Janos Follath24eed8d2019-11-22 13:21:35 +0000884 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
Valerio Setti43363f52022-12-14 08:53:23 +0100887#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100889 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 }
Valerio Setti43363f52022-12-14 08:53:23 +0100891#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 if (is384 != 0) {
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#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100897 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100899#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100904 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 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_finish(&ctx, output)) != 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
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100915exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000919}
920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000922
923/*
924 * FIPS-180-2 test vectors
925 */
Valerio Setti43363f52022-12-14 08:53:23 +0100926static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000927{
928 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 {
930 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
931 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 { "" }
933};
934
Valerio Setti43363f52022-12-14 08:53:23 +0100935static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000936{
937 3, 112, 1000
938};
939
Valerio Setti43363f52022-12-14 08:53:23 +0100940typedef const unsigned char (sha_test_sum_t)[64];
941
942/*
943 * SHA-384 test vectors
944 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200945#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100946static sha_test_sum_t sha384_test_sum[] =
947{
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
949 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
950 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
951 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
952 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
953 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
954 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
955 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
956 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
957 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
958 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
959 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
960 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
961 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
962 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
963 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
964 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100965 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
966};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200967#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000968
Valerio Setti43363f52022-12-14 08:53:23 +0100969/*
970 * SHA-512 test vectors
971 */
972#if defined(MBEDTLS_SHA512_C)
973static sha_test_sum_t sha512_test_sum[] =
974{
Paul Bakker5121ce52009-01-03 21:22:43 +0000975 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
976 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
977 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
978 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
979 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
980 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
981 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
982 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
983 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
984 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
985 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
986 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
987 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
988 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
989 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
990 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
991 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
992 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
993 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
994 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
995 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
996 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
997 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
998 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
999};
Valerio Setti43363f52022-12-14 08:53:23 +01001000#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001003{
Valerio Setti43363f52022-12-14 08:53:23 +01001004 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001005 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001006 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001008
Valerio Setti43363f52022-12-14 08:53:23 +01001009#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001011#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001013#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001015#endif
1016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1018 if (NULL == buf) {
1019 if (verbose != 0) {
1020 mbedtls_printf("Buffer allocation failed\n");
1021 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001022
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001024 }
1025
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 for (i = 0; i < 3; i++) {
1029 if (verbose != 0) {
1030 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1031 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001032
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001034 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001036
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 if (i == 2) {
1038 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 for (int j = 0; j < 1000; j++) {
1041 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1042 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001043 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 }
1045 }
1046 } else {
1047 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1048 sha_test_buflen[i]);
1049 if (ret != 0) {
1050 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001051 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001052 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001053
1054 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1055 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001056 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001059 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001060 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001061 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001062
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 if (verbose != 0) {
1064 mbedtls_printf("passed\n");
1065 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001066 }
1067
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 if (verbose != 0) {
1069 mbedtls_printf("\n");
1070 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001071
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001072 goto exit;
1073
1074fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 if (verbose != 0) {
1076 mbedtls_printf("failed\n");
1077 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001078
Paul Bakker5b4af392014-06-26 12:09:34 +02001079exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 mbedtls_sha512_free(&ctx);
1081 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001082
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001084}
1085
Valerio Setti898e7a32022-12-14 08:55:53 +01001086#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001087int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001088{
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001090}
Valerio Setti898e7a32022-12-14 08:55:53 +01001091#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001092
Valerio Setti898e7a32022-12-14 08:55:53 +01001093#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001094int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001095{
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001097}
Valerio Setti898e7a32022-12-14 08:55:53 +01001098#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001099
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001100#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001102#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001103
Valerio Setti43363f52022-12-14 08:53:23 +01001104#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */