blob: 0e99914dda0deb729686d2f6dc11024aba452673 [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Jerry Yua135dee2023-02-16 16:56:22 +080025#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
Jerry Yu6f86c192023-03-13 11:03:40 +080026 defined(__clang__) && __clang_major__ >= 7
Jerry Yua135dee2023-02-16 16:56:22 +080027/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
28 *
Jerry Yufc2e1282023-02-27 11:16:56 +080029 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
30 * these are normally only enabled by the -march option on the command line.
31 * By defining the macros ourselves we gain access to those declarations without
32 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080033 *
Dave Rodgmana0f10da2023-09-05 11:43:17 +010034 * `arm_neon.h` is included by common.h, so we put these defines
Jerry Yufc2e1282023-02-27 11:16:56 +080035 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080036 */
37#define __ARM_FEATURE_SHA512 1
Dave Rodgmandb6ab242023-03-14 16:03:57 +000038#define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG
Jerry Yu490bf082023-03-06 15:21:44 +080039#endif
Jerry Yua135dee2023-02-16 16:56:22 +080040
Gilles Peskinedb09ef62020-06-03 01:43:33 +020041#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000042
Valerio Setti43363f52022-12-14 08:53:23 +010043#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000044
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050046#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000047#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000048
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000049#if defined(_MSC_VER) || defined(__WATCOMC__)
50 #define UL64(x) x##ui64
51#else
52 #define UL64(x) x##ULL
53#endif
54
Rich Evans00ab4702015-02-06 13:43:58 +000055#include <string.h>
56
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000057#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010058
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000059#if defined(__aarch64__)
60# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010061 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080062/* *INDENT-OFF* */
Dave Rodgmana0f10da2023-09-05 11:43:17 +010063# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
Jerry Yu6b00f5a2023-05-04 16:30:21 +080064# error "Target does not support NEON instructions"
65# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080066/*
67 * Best performance comes from most recent compilers, with intrinsics and -O3.
68 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
69 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
70 *
71 * GCC < 8 won't work at all (lacks the sha512 instructions)
72 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
73 *
74 * Clang < 7 won't work at all (lacks the sha512 instructions)
75 * Clang 7-12 don't have intrinsics (but we work around that with inline
76 * assembler) or __ARM_FEATURE_SHA512
77 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
78 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
79 */
Dave Rodgmandb6ab242023-03-14 16:03:57 +000080# if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080081 /* Test Clang first, as it defines __GNUC__ */
Jerry Yu22a4d3e2023-04-28 17:43:40 +080082# if defined(__ARMCOMPILER_VERSION)
83# if __ARMCOMPILER_VERSION < 6090000
Jerry Yu8e96e782023-05-04 16:37:30 +080084# error "A more recent armclang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yub1d06bb2023-05-05 14:05:07 +080085# elif __ARMCOMPILER_VERSION == 6090000
86# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
87# else
Jerry Yu22a4d3e2023-04-28 17:43:40 +080088# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
89# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yub1d06bb2023-05-05 14:05:07 +080090# endif
Jerry Yu22a4d3e2023-04-28 17:43:40 +080091# elif defined(__clang__)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080092# if __clang_major__ < 7
93# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080094# else
Jerry Yu64e5d4a2023-02-15 11:46:57 +080095# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
96# define MBEDTLS_POP_TARGET_PRAGMA
97# endif
98# elif defined(__GNUC__)
99# if __GNUC__ < 8
100# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
101# else
Jerry Yu2f2c0492023-02-16 14:24:46 +0800102# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800103# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +0800104# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800105# endif
106# else
107# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
108# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800109# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800110/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000111# endif
112# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
113# if defined(__unix__)
114# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100115/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000116# include <sys/auxv.h>
117# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100118/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000119# include <signal.h>
120# endif
121# endif
122#elif defined(_M_ARM64)
123# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000125# include <arm64_neon.h>
126# endif
127#else
128# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
129# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
130#endif
131
132#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
133/*
134 * Capability detection code comes early, so we can disable
135 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
136 */
137#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100138static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000139{
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000141}
142#elif defined(__APPLE__)
143#include <sys/types.h>
144#include <sys/sysctl.h>
145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000147{
148 int value = 0;
149 size_t value_len = sizeof(value);
150
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
152 NULL, 0);
153 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000154}
Dave Rodgmanad71b6a2023-08-08 10:37:33 +0100155#elif defined(_M_ARM64) || defined(_M_ARM64EC)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000156/*
157 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
158 * available to pass to IsProcessorFeaturePresent() to check for
159 * SHA-512 support. So we fall back to the C code only.
160 */
161#if defined(_MSC_VER)
162#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
163#else
164#warning "No mechanism to detect A64_CRYPTO found, using C code only"
165#endif
166#elif defined(__unix__) && defined(SIG_SETMASK)
167/* Detection with SIGILL, setjmp() and longjmp() */
168#include <signal.h>
169#include <setjmp.h>
170
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000171static jmp_buf return_from_sigill;
172
173/*
174 * A64 SHA512 support detection via SIGILL
175 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100176static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000177{
178 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000180}
181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000183{
184 struct sigaction old_action, new_action;
185
186 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 if (sigprocmask(0, NULL, &old_mask)) {
188 return 0;
189 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000192 new_action.sa_flags = 0;
193 new_action.sa_handler = sigill_handler;
194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000196
197 static int ret = 0;
198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000200 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000202 ret = 1;
203 }
204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 sigaction(SIGILL, &old_action, NULL);
206 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000209}
210#else
211#warning "No mechanism to detect A64_CRYPTO found, using C code only"
212#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
213#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
214
215#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
216
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200217#if !defined(MBEDTLS_SHA512_ALT)
218
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000219#define SHA512_BLOCK_SIZE 128
220
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200221#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100222static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200223{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100224 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200225}
226#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100227#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200228#endif /* MBEDTLS_SHA512_SMALLER */
229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200231{
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200233}
234
Gilles Peskine449bd832023-01-11 14:50:10 +0100235void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200236{
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200238 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200240
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200242}
243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
245 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200246{
247 *dst = *src;
248}
249
Paul Bakker5121ce52009-01-03 21:22:43 +0000250/*
251 * SHA-512 context setup
252 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100253int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000254{
Valerio Setti43363f52022-12-14 08:53:23 +0100255#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100257 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 }
Valerio Setti43363f52022-12-14 08:53:23 +0100259#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100261 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 }
Valerio Setti43363f52022-12-14 08:53:23 +0100263#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100265 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100267#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000268
Paul Bakker5121ce52009-01-03 21:22:43 +0000269 ctx->total[0] = 0;
270 ctx->total[1] = 0;
271
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100273#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000274 ctx->state[0] = UL64(0x6A09E667F3BCC908);
275 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
276 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
277 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
278 ctx->state[4] = UL64(0x510E527FADE682D1);
279 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
280 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
281 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100282#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100284#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
286 ctx->state[1] = UL64(0x629A292A367CD507);
287 ctx->state[2] = UL64(0x9159015A3070DD17);
288 ctx->state[3] = UL64(0x152FECD8F70E5939);
289 ctx->state[4] = UL64(0x67332667FFC00B31);
290 ctx->state[5] = UL64(0x8EB44A8768581511);
291 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
292 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200293#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 }
295
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200296#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000297 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200298#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100299
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000301}
302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200304
305/*
306 * Round constants
307 */
308static const uint64_t K[80] =
309{
310 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
311 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
312 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
313 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
314 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
315 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
316 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
317 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
318 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
319 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
320 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
321 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
322 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
323 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
324 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
325 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
326 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
327 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
328 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
329 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
330 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
331 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
332 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
333 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
334 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
335 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
336 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
337 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
338 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
339 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
340 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
341 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
342 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
343 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
344 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
345 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
346 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
347 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
348 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
349 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
350};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000351#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200352
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000353#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
354 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
355
356#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
357# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
358# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
359#endif
360
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000361/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
362 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
363 */
364
365#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 (__clang_major__ < 13 || \
367 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000368static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
369{
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
371 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000372}
373static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
374{
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
376 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000377}
378static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
379{
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
381 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000382}
383static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
384{
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
386 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000387}
388#endif /* __clang__ etc */
389
390static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000392{
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
394 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
395 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
396 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000397
398 size_t processed = 0;
399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 for (;
401 len >= SHA512_BLOCK_SIZE;
402 processed += SHA512_BLOCK_SIZE,
403 msg += SHA512_BLOCK_SIZE,
404 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000405 uint64x2_t initial_sum, sum, intermed;
406
407 uint64x2_t ab_orig = ab;
408 uint64x2_t cd_orig = cd;
409 uint64x2_t ef_orig = ef;
410 uint64x2_t gh_orig = gh;
411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
413 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
414 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
415 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
416 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
417 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
418 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
419 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000420
421#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
423 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
424 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
425 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
426 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
427 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
428 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
429 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000430#endif
431
432 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
434 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
435 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
436 gh = vsha512h2q_u64(intermed, cd, ab);
437 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000438
439 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
441 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
442 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
443 ef = vsha512h2q_u64(intermed, ab, gh);
444 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000445
446 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
448 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
449 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
450 cd = vsha512h2q_u64(intermed, gh, ef);
451 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000452
453 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
455 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
456 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
457 ab = vsha512h2q_u64(intermed, ef, cd);
458 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000459
460 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
462 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
463 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
464 gh = vsha512h2q_u64(intermed, cd, ab);
465 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000466
467 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
469 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
470 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
471 ef = vsha512h2q_u64(intermed, ab, gh);
472 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000473
474 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
476 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
477 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
478 cd = vsha512h2q_u64(intermed, gh, ef);
479 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000480
481 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
483 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
484 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
485 ab = vsha512h2q_u64(intermed, ef, cd);
486 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000487
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000489 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
491 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
492 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
493 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
494 gh = vsha512h2q_u64(intermed, cd, ab);
495 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000496
497 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
499 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
500 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
501 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
502 ef = vsha512h2q_u64(intermed, ab, gh);
503 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000504
505 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
507 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
508 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
509 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
510 cd = vsha512h2q_u64(intermed, gh, ef);
511 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000512
513 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
515 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
516 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
517 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
518 ab = vsha512h2q_u64(intermed, ef, cd);
519 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000520
521 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
523 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
524 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
525 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
526 gh = vsha512h2q_u64(intermed, cd, ab);
527 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000528
529 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
531 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
532 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
533 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
534 ef = vsha512h2q_u64(intermed, ab, gh);
535 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000536
537 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
539 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
540 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
541 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
542 cd = vsha512h2q_u64(intermed, gh, ef);
543 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000544
545 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
547 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
548 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
549 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
550 ab = vsha512h2q_u64(intermed, ef, cd);
551 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000552 }
553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 ab = vaddq_u64(ab, ab_orig);
555 cd = vaddq_u64(cd, cd_orig);
556 ef = vaddq_u64(ef, ef_orig);
557 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000558 }
559
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 vst1q_u64(&ctx->state[0], ab);
561 vst1q_u64(&ctx->state[2], cd);
562 vst1q_u64(&ctx->state[4], ef);
563 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000564
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000566}
567
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100568#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
569/*
570 * This function is for internal use only if we are building both C and A64
571 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
572 */
573static
574#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100575int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
576 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000577{
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
579 SHA512_BLOCK_SIZE) ==
580 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000581}
582
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100583#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
584
Jerry Yu92fc5382023-02-16 11:17:11 +0800585#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800586#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800587#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800588#elif defined(__GNUC__)
589#pragma GCC pop_options
590#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800591#undef MBEDTLS_POP_TARGET_PRAGMA
592#endif
593
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000594
595#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
596#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
597#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
598#endif
599
600
601#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
602
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100603#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
604/*
605 * This function is for internal use only if we are building both C and A64
606 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
607 */
608static
609#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100610int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
611 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000612{
613 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200615 uint64_t temp1, temp2, W[80];
616 uint64_t A[8];
617 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619#define SHR(x, n) ((x) >> (n))
620#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100623#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
626#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
629#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200632 do \
633 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
635 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200636 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200640 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200642
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200643#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 for (i = 0; i < 80; i++) {
645 if (i < 16) {
646 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
647 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200648 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200650 }
651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
653 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200654
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200655 local.temp1 = local.A[7]; local.A[7] = local.A[6];
656 local.A[6] = local.A[5]; local.A[5] = local.A[4];
657 local.A[4] = local.A[3]; local.A[3] = local.A[2];
658 local.A[2] = local.A[1]; local.A[1] = local.A[0];
659 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200660 }
661#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 for (i = 0; i < 16; i++) {
663 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 }
665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200667 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000669 }
670
Paul Bakker5121ce52009-01-03 21:22:43 +0000671 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 do {
673 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
674 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
675 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
676 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
677 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
678 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
679 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
680 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
681 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
682 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
683 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
684 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
685 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
686 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
687 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
688 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
689 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200690#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200693 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100695
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200696 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000700}
Jaeden Amero041039f2018-02-19 15:28:08 +0000701
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000702#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
703
704
705#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
706
707static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000709{
710 size_t processed = 0;
711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 while (len >= SHA512_BLOCK_SIZE) {
713 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
714 return 0;
715 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000716
717 data += SHA512_BLOCK_SIZE;
718 len -= SHA512_BLOCK_SIZE;
719
720 processed += SHA512_BLOCK_SIZE;
721 }
722
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000724}
725
726#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
727
728
729#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
730
Gilles Peskine449bd832023-01-11 14:50:10 +0100731static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000732{
733 static int done = 0;
734 static int supported = 0;
735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000737 supported = mbedtls_a64_crypto_sha512_determine_support();
738 done = 1;
739 }
740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000742}
743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
745 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000746{
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 if (mbedtls_a64_crypto_sha512_has_support()) {
748 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
749 } else {
750 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
751 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000752}
753
Gilles Peskine449bd832023-01-11 14:50:10 +0100754int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
755 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000756{
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if (mbedtls_a64_crypto_sha512_has_support()) {
758 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
759 } else {
760 return mbedtls_internal_sha512_process_c(ctx, data);
761 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000762}
763
764#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000765
766/*
767 * SHA-512 process buffer
768 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100769int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
770 const unsigned char *input,
771 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000772{
Janos Follath24eed8d2019-11-22 13:21:35 +0000773 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000774 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000775 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000776
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 if (ilen == 0) {
778 return 0;
779 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
Paul Bakkerb8213a12011-07-11 08:16:18 +0000781 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000782 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000783
Paul Bakker5c2364c2012-10-01 14:41:15 +0000784 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000787 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 if (left && ilen >= fill) {
791 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
794 return ret;
795 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100796
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 input += fill;
798 ilen -= fill;
799 left = 0;
800 }
801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000803 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 mbedtls_internal_sha512_process_many(ctx, input, ilen);
805 if (processed < SHA512_BLOCK_SIZE) {
806 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
807 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100808
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000809 input += processed;
810 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000811 }
812
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 if (ilen > 0) {
814 memcpy((void *) (ctx->buffer + left), input, ilen);
815 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100816
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000818}
819
Paul Bakker5121ce52009-01-03 21:22:43 +0000820/*
821 * SHA-512 final digest
822 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100823int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
824 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000825{
Janos Follath24eed8d2019-11-22 13:21:35 +0000826 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200827 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000828 uint64_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100829 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000830
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200831 /*
832 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
833 */
834 used = ctx->total[0] & 0x7F;
835
836 ctx->buffer[used++] = 0x80;
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200839 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 memset(ctx->buffer + used, 0, 112 - used);
841 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200842 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200844
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 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200848
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200850 }
851
852 /*
853 * Add message length
854 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 high = (ctx->total[0] >> 61)
856 | (ctx->total[1] << 3);
857 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 sha512_put_uint64_be(high, ctx->buffer, 112);
860 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100863 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000865
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200866 /*
867 * Output final state
868 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 sha512_put_uint64_be(ctx->state[0], output, 0);
870 sha512_put_uint64_be(ctx->state[1], output, 8);
871 sha512_put_uint64_be(ctx->state[2], output, 16);
872 sha512_put_uint64_be(ctx->state[3], output, 24);
873 sha512_put_uint64_be(ctx->state[4], output, 32);
874 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200876#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100877 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200878#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 if (!truncated) {
880 sha512_put_uint64_be(ctx->state[6], output, 48);
881 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000882 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100883
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100884 ret = 0;
885
886exit:
887 mbedtls_sha512_free(ctx);
888 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000889}
890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200892
Paul Bakker5121ce52009-01-03 21:22:43 +0000893/*
894 * output = SHA-512( input buffer )
895 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100896int mbedtls_sha512(const unsigned char *input,
897 size_t ilen,
898 unsigned char *output,
899 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000900{
Janos Follath24eed8d2019-11-22 13:21:35 +0000901 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000903
Valerio Setti43363f52022-12-14 08:53:23 +0100904#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100906 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 }
Valerio Setti43363f52022-12-14 08:53:23 +0100908#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100910 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 }
Valerio Setti43363f52022-12-14 08:53:23 +0100912#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100914 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100916#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100919
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100921 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100925 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100927
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100929 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100931
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100932exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000936}
937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
940/*
941 * FIPS-180-2 test vectors
942 */
Valerio Setti43363f52022-12-14 08:53:23 +0100943static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000944{
945 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 {
947 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
948 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 { "" }
950};
951
Valerio Setti43363f52022-12-14 08:53:23 +0100952static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000953{
954 3, 112, 1000
955};
956
Valerio Setti43363f52022-12-14 08:53:23 +0100957typedef const unsigned char (sha_test_sum_t)[64];
958
959/*
960 * SHA-384 test vectors
961 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200962#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100963static sha_test_sum_t sha384_test_sum[] =
964{
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
966 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
967 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
968 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
969 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
970 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
971 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
972 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
973 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
974 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
975 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
976 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
977 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
978 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
979 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
980 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
981 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100982 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
983};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200984#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000985
Valerio Setti43363f52022-12-14 08:53:23 +0100986/*
987 * SHA-512 test vectors
988 */
989#if defined(MBEDTLS_SHA512_C)
990static sha_test_sum_t sha512_test_sum[] =
991{
Paul Bakker5121ce52009-01-03 21:22:43 +0000992 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
993 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
994 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
995 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
996 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
997 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
998 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
999 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
1000 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
1001 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
1002 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
1003 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
1004 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
1005 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
1006 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
1007 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
1008 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
1009 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1010 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1011 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1012 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1013 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1014 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1015 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1016};
Valerio Setti43363f52022-12-14 08:53:23 +01001017#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001018
Gilles Peskine449bd832023-01-11 14:50:10 +01001019static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001020{
Valerio Setti43363f52022-12-14 08:53:23 +01001021 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001022 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001023 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Valerio Setti43363f52022-12-14 08:53:23 +01001026#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001028#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001030#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001032#endif
1033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1035 if (NULL == buf) {
1036 if (verbose != 0) {
1037 mbedtls_printf("Buffer allocation failed\n");
1038 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001041 }
1042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 for (i = 0; i < 3; i++) {
1046 if (verbose != 0) {
1047 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1048 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001049
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001051 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001053
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 if (i == 2) {
1055 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001056
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 for (int j = 0; j < 1000; j++) {
1058 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1059 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001060 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 }
1062 }
1063 } else {
1064 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1065 sha_test_buflen[i]);
1066 if (ret != 0) {
1067 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001068 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001069 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001070
1071 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1072 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001073 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001074
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001076 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001077 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001078 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 if (verbose != 0) {
1081 mbedtls_printf("passed\n");
1082 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001083 }
1084
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 if (verbose != 0) {
1086 mbedtls_printf("\n");
1087 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001088
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001089 goto exit;
1090
1091fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 if (verbose != 0) {
1093 mbedtls_printf("failed\n");
1094 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001095
Paul Bakker5b4af392014-06-26 12:09:34 +02001096exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 mbedtls_sha512_free(&ctx);
1098 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001099
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001101}
1102
Valerio Setti898e7a32022-12-14 08:55:53 +01001103#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001104int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001105{
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001107}
Valerio Setti898e7a32022-12-14 08:55:53 +01001108#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001109
Valerio Setti898e7a32022-12-14 08:55:53 +01001110#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001111int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001112{
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001114}
Valerio Setti898e7a32022-12-14 08:55:53 +01001115#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001116
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001117#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001119#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001120
Valerio Setti43363f52022-12-14 08:53:23 +01001121#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */