blob: 05b89408f8e4562fee4b6ae4dc11eac5c826ca91 [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
Dave Rodgman0a487172023-09-15 11:52:06 +0100122#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000123# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
124# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
125#endif
126
127#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
128/*
129 * Capability detection code comes early, so we can disable
130 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
131 */
132#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100133static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000134{
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000136}
137#elif defined(__APPLE__)
138#include <sys/types.h>
139#include <sys/sysctl.h>
140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000142{
143 int value = 0;
144 size_t value_len = sizeof(value);
145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
147 NULL, 0);
148 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000149}
Dave Rodgman0a487172023-09-15 11:52:06 +0100150#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000151/*
152 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
153 * available to pass to IsProcessorFeaturePresent() to check for
154 * SHA-512 support. So we fall back to the C code only.
155 */
156#if defined(_MSC_VER)
157#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
158#else
159#warning "No mechanism to detect A64_CRYPTO found, using C code only"
160#endif
161#elif defined(__unix__) && defined(SIG_SETMASK)
162/* Detection with SIGILL, setjmp() and longjmp() */
163#include <signal.h>
164#include <setjmp.h>
165
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000166static jmp_buf return_from_sigill;
167
168/*
169 * A64 SHA512 support detection via SIGILL
170 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100171static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000172{
173 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000175}
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000178{
179 struct sigaction old_action, new_action;
180
181 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 if (sigprocmask(0, NULL, &old_mask)) {
183 return 0;
184 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000187 new_action.sa_flags = 0;
188 new_action.sa_handler = sigill_handler;
189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000191
192 static int ret = 0;
193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000195 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000197 ret = 1;
198 }
199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 sigaction(SIGILL, &old_action, NULL);
201 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000204}
205#else
206#warning "No mechanism to detect A64_CRYPTO found, using C code only"
207#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
208#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
209
210#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
211
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200212#if !defined(MBEDTLS_SHA512_ALT)
213
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000214#define SHA512_BLOCK_SIZE 128
215
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200216#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100217static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200218{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100219 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200220}
221#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100222#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200223#endif /* MBEDTLS_SHA512_SMALLER */
224
Gilles Peskine449bd832023-01-11 14:50:10 +0100225void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200226{
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200228}
229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200231{
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200233 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200237}
238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
240 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200241{
242 *dst = *src;
243}
244
Paul Bakker5121ce52009-01-03 21:22:43 +0000245/*
246 * SHA-512 context setup
247 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100248int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000249{
Valerio Setti43363f52022-12-14 08:53:23 +0100250#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100252 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 }
Valerio Setti43363f52022-12-14 08:53:23 +0100254#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100256 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 }
Valerio Setti43363f52022-12-14 08:53:23 +0100258#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100260 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100262#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000263
Paul Bakker5121ce52009-01-03 21:22:43 +0000264 ctx->total[0] = 0;
265 ctx->total[1] = 0;
266
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100268#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000269 ctx->state[0] = UL64(0x6A09E667F3BCC908);
270 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
271 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
272 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
273 ctx->state[4] = UL64(0x510E527FADE682D1);
274 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
275 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
276 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100277#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100279#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
281 ctx->state[1] = UL64(0x629A292A367CD507);
282 ctx->state[2] = UL64(0x9159015A3070DD17);
283 ctx->state[3] = UL64(0x152FECD8F70E5939);
284 ctx->state[4] = UL64(0x67332667FFC00B31);
285 ctx->state[5] = UL64(0x8EB44A8768581511);
286 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
287 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200288#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 }
290
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200291#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200293#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100294
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000296}
297
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200299
300/*
301 * Round constants
302 */
303static const uint64_t K[80] =
304{
305 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
306 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
307 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
308 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
309 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
310 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
311 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
312 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
313 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
314 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
315 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
316 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
317 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
318 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
319 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
320 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
321 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
322 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
323 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
324 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
325 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
326 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
327 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
328 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
329 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
330 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
331 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
332 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
333 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
334 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
335 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
336 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
337 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
338 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
339 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
340 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
341 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
342 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
343 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
344 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
345};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000346#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200347
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000348#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
349 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
350
351#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
352# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
353# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
354#endif
355
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000356/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
357 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
358 */
359
360#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 (__clang_major__ < 13 || \
362 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000363static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
364{
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
366 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000367}
368static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
369{
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
371 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000372}
373static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
374{
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
376 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000377}
378static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
379{
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
381 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000382}
383#endif /* __clang__ etc */
384
385static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000387{
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
389 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
390 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
391 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000392
393 size_t processed = 0;
394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 for (;
396 len >= SHA512_BLOCK_SIZE;
397 processed += SHA512_BLOCK_SIZE,
398 msg += SHA512_BLOCK_SIZE,
399 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000400 uint64x2_t initial_sum, sum, intermed;
401
402 uint64x2_t ab_orig = ab;
403 uint64x2_t cd_orig = cd;
404 uint64x2_t ef_orig = ef;
405 uint64x2_t gh_orig = gh;
406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
408 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
409 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
410 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
411 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
412 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
413 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
414 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000415
416#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
418 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
419 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
420 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
421 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
422 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
423 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
424 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000425#endif
426
427 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
429 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
430 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
431 gh = vsha512h2q_u64(intermed, cd, ab);
432 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000433
434 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
436 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
437 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
438 ef = vsha512h2q_u64(intermed, ab, gh);
439 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000440
441 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
443 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
444 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
445 cd = vsha512h2q_u64(intermed, gh, ef);
446 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000447
448 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
450 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
451 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
452 ab = vsha512h2q_u64(intermed, ef, cd);
453 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000454
455 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
457 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
458 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
459 gh = vsha512h2q_u64(intermed, cd, ab);
460 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000461
462 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
464 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
465 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
466 ef = vsha512h2q_u64(intermed, ab, gh);
467 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000468
469 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
471 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
472 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
473 cd = vsha512h2q_u64(intermed, gh, ef);
474 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000475
476 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
478 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
479 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
480 ab = vsha512h2q_u64(intermed, ef, cd);
481 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000484 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
486 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
487 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
488 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
489 gh = vsha512h2q_u64(intermed, cd, ab);
490 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000491
492 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
494 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
495 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
496 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
497 ef = vsha512h2q_u64(intermed, ab, gh);
498 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000499
500 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
502 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
503 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
504 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
505 cd = vsha512h2q_u64(intermed, gh, ef);
506 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000507
508 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
510 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
511 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
512 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
513 ab = vsha512h2q_u64(intermed, ef, cd);
514 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000515
516 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
518 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
519 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
520 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
521 gh = vsha512h2q_u64(intermed, cd, ab);
522 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000523
524 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
526 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
527 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
528 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
529 ef = vsha512h2q_u64(intermed, ab, gh);
530 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000531
532 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
534 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
535 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
536 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
537 cd = vsha512h2q_u64(intermed, gh, ef);
538 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000539
540 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
542 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
543 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
544 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
545 ab = vsha512h2q_u64(intermed, ef, cd);
546 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000547 }
548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 ab = vaddq_u64(ab, ab_orig);
550 cd = vaddq_u64(cd, cd_orig);
551 ef = vaddq_u64(ef, ef_orig);
552 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000553 }
554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 vst1q_u64(&ctx->state[0], ab);
556 vst1q_u64(&ctx->state[2], cd);
557 vst1q_u64(&ctx->state[4], ef);
558 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000559
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000561}
562
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100563#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
564/*
565 * This function is for internal use only if we are building both C and A64
566 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
567 */
568static
569#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100570int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
571 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000572{
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
574 SHA512_BLOCK_SIZE) ==
575 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000576}
577
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100578#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
579
Jerry Yu92fc5382023-02-16 11:17:11 +0800580#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800581#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800582#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800583#elif defined(__GNUC__)
584#pragma GCC pop_options
585#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800586#undef MBEDTLS_POP_TARGET_PRAGMA
587#endif
588
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000589
590#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
591#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
592#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
593#endif
594
595
596#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
597
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100598#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
599/*
600 * This function is for internal use only if we are building both C and A64
601 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
602 */
603static
604#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100605int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
606 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000607{
608 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200610 uint64_t temp1, temp2, W[80];
611 uint64_t A[8];
612 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614#define SHR(x, n) ((x) >> (n))
615#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
617#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100618#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
621#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
Gilles Peskine449bd832023-01-11 14:50:10 +0100623#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
624#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200627 do \
628 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
630 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200631 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200635 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200637
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200638#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 for (i = 0; i < 80; i++) {
640 if (i < 16) {
641 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
642 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200643 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200645 }
646
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
648 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200649
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200650 local.temp1 = local.A[7]; local.A[7] = local.A[6];
651 local.A[6] = local.A[5]; local.A[5] = local.A[4];
652 local.A[4] = local.A[3]; local.A[3] = local.A[2];
653 local.A[2] = local.A[1]; local.A[1] = local.A[0];
654 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200655 }
656#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 for (i = 0; i < 16; i++) {
658 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000659 }
660
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200662 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 }
665
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 do {
668 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
669 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
670 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
671 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
672 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
673 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
674 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
675 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
676 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
677 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
678 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
679 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
680 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
681 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
682 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
683 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
684 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200685#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200688 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100690
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200691 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000695}
Jaeden Amero041039f2018-02-19 15:28:08 +0000696
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000697#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
698
699
700#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
701
702static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000704{
705 size_t processed = 0;
706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 while (len >= SHA512_BLOCK_SIZE) {
708 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
709 return 0;
710 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000711
712 data += SHA512_BLOCK_SIZE;
713 len -= SHA512_BLOCK_SIZE;
714
715 processed += SHA512_BLOCK_SIZE;
716 }
717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000719}
720
721#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
722
723
724#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000727{
728 static int done = 0;
729 static int supported = 0;
730
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000732 supported = mbedtls_a64_crypto_sha512_determine_support();
733 done = 1;
734 }
735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000737}
738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
740 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000741{
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 if (mbedtls_a64_crypto_sha512_has_support()) {
743 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
744 } else {
745 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
746 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000747}
748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
750 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000751{
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 if (mbedtls_a64_crypto_sha512_has_support()) {
753 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
754 } else {
755 return mbedtls_internal_sha512_process_c(ctx, data);
756 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000757}
758
759#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000760
761/*
762 * SHA-512 process buffer
763 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100764int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
765 const unsigned char *input,
766 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000767{
Janos Follath24eed8d2019-11-22 13:21:35 +0000768 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000769 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000770 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if (ilen == 0) {
773 return 0;
774 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000775
Paul Bakkerb8213a12011-07-11 08:16:18 +0000776 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000777 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000778
Paul Bakker5c2364c2012-10-01 14:41:15 +0000779 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000782 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000784
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 if (left && ilen >= fill) {
786 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100787
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
789 return ret;
790 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100791
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 input += fill;
793 ilen -= fill;
794 left = 0;
795 }
796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000798 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 mbedtls_internal_sha512_process_many(ctx, input, ilen);
800 if (processed < SHA512_BLOCK_SIZE) {
801 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
802 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100803
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000804 input += processed;
805 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000806 }
807
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 if (ilen > 0) {
809 memcpy((void *) (ctx->buffer + left), input, ilen);
810 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100811
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000813}
814
Paul Bakker5121ce52009-01-03 21:22:43 +0000815/*
816 * SHA-512 final digest
817 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100818int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
819 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000820{
Janos Follath24eed8d2019-11-22 13:21:35 +0000821 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200822 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000823 uint64_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100824 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200826 /*
827 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
828 */
829 used = ctx->total[0] & 0x7F;
830
831 ctx->buffer[used++] = 0x80;
832
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200834 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 memset(ctx->buffer + used, 0, 112 - used);
836 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200837 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100841 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200843
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200845 }
846
847 /*
848 * Add message length
849 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 high = (ctx->total[0] >> 61)
851 | (ctx->total[1] << 3);
852 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 sha512_put_uint64_be(high, ctx->buffer, 112);
855 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000856
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100858 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000860
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200861 /*
862 * Output final state
863 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 sha512_put_uint64_be(ctx->state[0], output, 0);
865 sha512_put_uint64_be(ctx->state[1], output, 8);
866 sha512_put_uint64_be(ctx->state[2], output, 16);
867 sha512_put_uint64_be(ctx->state[3], output, 24);
868 sha512_put_uint64_be(ctx->state[4], output, 32);
869 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000870
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200871#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100872 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200873#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 if (!truncated) {
875 sha512_put_uint64_be(ctx->state[6], output, 48);
876 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000877 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100878
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100879 ret = 0;
880
881exit:
882 mbedtls_sha512_free(ctx);
883 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000884}
885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200886#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200887
Paul Bakker5121ce52009-01-03 21:22:43 +0000888/*
889 * output = SHA-512( input buffer )
890 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100891int mbedtls_sha512(const unsigned char *input,
892 size_t ilen,
893 unsigned char *output,
894 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000895{
Janos Follath24eed8d2019-11-22 13:21:35 +0000896 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000898
Valerio Setti43363f52022-12-14 08:53:23 +0100899#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100901 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 }
Valerio Setti43363f52022-12-14 08:53:23 +0100903#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100905 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 }
Valerio Setti43363f52022-12-14 08:53:23 +0100907#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100909 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100911#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100914
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100916 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100920 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100922
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100924 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100926
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100927exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000931}
932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
935/*
936 * FIPS-180-2 test vectors
937 */
Valerio Setti43363f52022-12-14 08:53:23 +0100938static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000939{
940 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 {
942 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
943 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 { "" }
945};
946
Valerio Setti43363f52022-12-14 08:53:23 +0100947static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000948{
949 3, 112, 1000
950};
951
Valerio Setti43363f52022-12-14 08:53:23 +0100952typedef const unsigned char (sha_test_sum_t)[64];
953
954/*
955 * SHA-384 test vectors
956 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200957#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100958static sha_test_sum_t sha384_test_sum[] =
959{
Paul Bakker5121ce52009-01-03 21:22:43 +0000960 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
961 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
962 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
963 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
964 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
965 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
966 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
967 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
968 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
969 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
970 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
971 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
972 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
973 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
974 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
975 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
976 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100977 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
978};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200979#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000980
Valerio Setti43363f52022-12-14 08:53:23 +0100981/*
982 * SHA-512 test vectors
983 */
984#if defined(MBEDTLS_SHA512_C)
985static sha_test_sum_t sha512_test_sum[] =
986{
Paul Bakker5121ce52009-01-03 21:22:43 +0000987 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
988 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
989 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
990 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
991 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
992 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
993 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
994 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
995 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
996 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
997 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
998 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
999 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
1000 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
1001 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
1002 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
1003 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
1004 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1005 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1006 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1007 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1008 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1009 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1010 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1011};
Valerio Setti43363f52022-12-14 08:53:23 +01001012#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001015{
Valerio Setti43363f52022-12-14 08:53:23 +01001016 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001017 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001018 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
Valerio Setti43363f52022-12-14 08:53:23 +01001021#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001023#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001025#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001027#endif
1028
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1030 if (NULL == buf) {
1031 if (verbose != 0) {
1032 mbedtls_printf("Buffer allocation failed\n");
1033 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001036 }
1037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 for (i = 0; i < 3; i++) {
1041 if (verbose != 0) {
1042 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1043 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001046 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 if (i == 2) {
1050 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 for (int j = 0; j < 1000; j++) {
1053 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1054 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001055 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 }
1057 }
1058 } else {
1059 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1060 sha_test_buflen[i]);
1061 if (ret != 0) {
1062 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001063 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001064 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001065
1066 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1067 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001068 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001071 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001072 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001073 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001074
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 if (verbose != 0) {
1076 mbedtls_printf("passed\n");
1077 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001078 }
1079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 if (verbose != 0) {
1081 mbedtls_printf("\n");
1082 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001083
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001084 goto exit;
1085
1086fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 if (verbose != 0) {
1088 mbedtls_printf("failed\n");
1089 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001090
Paul Bakker5b4af392014-06-26 12:09:34 +02001091exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 mbedtls_sha512_free(&ctx);
1093 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001094
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001096}
1097
Valerio Setti898e7a32022-12-14 08:55:53 +01001098#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001099int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001100{
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001102}
Valerio Setti898e7a32022-12-14 08:55:53 +01001103#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001104
Valerio Setti898e7a32022-12-14 08:55:53 +01001105#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001106int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001107{
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001109}
Valerio Setti898e7a32022-12-14 08:55:53 +01001110#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001111
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001112#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001115
Valerio Setti43363f52022-12-14 08:53:23 +01001116#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */