blob: 23e8745a529ca4c39360852c8c407c9931548150 [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 *
Jerry Yufc2e1282023-02-27 11:16:56 +080034 * `arm_neon.h` could be included by any header file, so we put these defines
35 * 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* */
Jerry Yu6b00f5a2023-05-04 16:30:21 +080063# ifdef __ARM_NEON
64# include <arm_neon.h>
65# else
66# error "Target does not support NEON instructions"
67# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080068/*
69 * Best performance comes from most recent compilers, with intrinsics and -O3.
70 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
71 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
72 *
73 * GCC < 8 won't work at all (lacks the sha512 instructions)
74 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
75 *
76 * Clang < 7 won't work at all (lacks the sha512 instructions)
77 * Clang 7-12 don't have intrinsics (but we work around that with inline
78 * assembler) or __ARM_FEATURE_SHA512
79 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
80 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
81 */
Dave Rodgmandb6ab242023-03-14 16:03:57 +000082# if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080083 /* Test Clang first, as it defines __GNUC__ */
Jerry Yu22a4d3e2023-04-28 17:43:40 +080084# if defined(__ARMCOMPILER_VERSION)
85# if __ARMCOMPILER_VERSION < 6090000
Jerry Yu8e96e782023-05-04 16:37:30 +080086# error "A more recent armclang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yub1d06bb2023-05-05 14:05:07 +080087# elif __ARMCOMPILER_VERSION == 6090000
88# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
89# else
Jerry Yu22a4d3e2023-04-28 17:43:40 +080090# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
91# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yub1d06bb2023-05-05 14:05:07 +080092# endif
Jerry Yu22a4d3e2023-04-28 17:43:40 +080093# elif defined(__clang__)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080094# if __clang_major__ < 7
95# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080096# else
Jerry Yu64e5d4a2023-02-15 11:46:57 +080097# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
98# define MBEDTLS_POP_TARGET_PRAGMA
99# endif
100# elif defined(__GNUC__)
101# if __GNUC__ < 8
102# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
103# else
Jerry Yu2f2c0492023-02-16 14:24:46 +0800104# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800105# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +0800106# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800107# endif
108# else
109# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
110# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800111# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800112/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000113# endif
114# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
115# if defined(__unix__)
116# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100117/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000118# include <sys/auxv.h>
119# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100120/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000121# include <signal.h>
122# endif
123# endif
124#elif defined(_M_ARM64)
125# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000127# include <arm64_neon.h>
128# endif
129#else
130# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
131# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
132#endif
133
134#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
135/*
136 * Capability detection code comes early, so we can disable
137 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
138 */
139#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100140static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000141{
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000143}
144#elif defined(__APPLE__)
145#include <sys/types.h>
146#include <sys/sysctl.h>
147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000149{
150 int value = 0;
151 size_t value_len = sizeof(value);
152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
154 NULL, 0);
155 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000156}
Dave Rodgmanad71b6a2023-08-08 10:37:33 +0100157#elif defined(_M_ARM64) || defined(_M_ARM64EC)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000158/*
159 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
160 * available to pass to IsProcessorFeaturePresent() to check for
161 * SHA-512 support. So we fall back to the C code only.
162 */
163#if defined(_MSC_VER)
164#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
165#else
166#warning "No mechanism to detect A64_CRYPTO found, using C code only"
167#endif
168#elif defined(__unix__) && defined(SIG_SETMASK)
169/* Detection with SIGILL, setjmp() and longjmp() */
170#include <signal.h>
171#include <setjmp.h>
172
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000173static jmp_buf return_from_sigill;
174
175/*
176 * A64 SHA512 support detection via SIGILL
177 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100178static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000179{
180 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000182}
183
Gilles Peskine449bd832023-01-11 14:50:10 +0100184static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000185{
186 struct sigaction old_action, new_action;
187
188 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 if (sigprocmask(0, NULL, &old_mask)) {
190 return 0;
191 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000194 new_action.sa_flags = 0;
195 new_action.sa_handler = sigill_handler;
196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000198
199 static int ret = 0;
200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000202 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000204 ret = 1;
205 }
206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 sigaction(SIGILL, &old_action, NULL);
208 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000211}
212#else
213#warning "No mechanism to detect A64_CRYPTO found, using C code only"
214#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
215#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
216
217#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
218
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200219#if !defined(MBEDTLS_SHA512_ALT)
220
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000221#define SHA512_BLOCK_SIZE 128
222
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200223#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100224static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200225{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100226 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200227}
228#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100229#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200230#endif /* MBEDTLS_SHA512_SMALLER */
231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200233{
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200235}
236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200238{
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200240 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200242
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200244}
245
Gilles Peskine449bd832023-01-11 14:50:10 +0100246void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
247 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200248{
249 *dst = *src;
250}
251
Paul Bakker5121ce52009-01-03 21:22:43 +0000252/*
253 * SHA-512 context setup
254 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100255int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000256{
Valerio Setti43363f52022-12-14 08:53:23 +0100257#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100259 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 }
Valerio Setti43363f52022-12-14 08:53:23 +0100261#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100263 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 }
Valerio Setti43363f52022-12-14 08:53:23 +0100265#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100267 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100269#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000270
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 ctx->total[0] = 0;
272 ctx->total[1] = 0;
273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100275#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000276 ctx->state[0] = UL64(0x6A09E667F3BCC908);
277 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
278 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
279 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
280 ctx->state[4] = UL64(0x510E527FADE682D1);
281 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
282 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
283 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100284#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100286#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
288 ctx->state[1] = UL64(0x629A292A367CD507);
289 ctx->state[2] = UL64(0x9159015A3070DD17);
290 ctx->state[3] = UL64(0x152FECD8F70E5939);
291 ctx->state[4] = UL64(0x67332667FFC00B31);
292 ctx->state[5] = UL64(0x8EB44A8768581511);
293 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
294 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200295#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000296 }
297
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200298#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200300#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000303}
304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200306
307/*
308 * Round constants
309 */
310static const uint64_t K[80] =
311{
312 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
313 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
314 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
315 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
316 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
317 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
318 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
319 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
320 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
321 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
322 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
323 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
324 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
325 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
326 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
327 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
328 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
329 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
330 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
331 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
332 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
333 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
334 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
335 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
336 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
337 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
338 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
339 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
340 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
341 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
342 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
343 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
344 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
345 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
346 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
347 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
348 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
349 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
350 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
351 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
352};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000353#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200354
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000355#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
356 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
357
358#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
359# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
360# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
361#endif
362
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000363/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
364 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
365 */
366
367#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 (__clang_major__ < 13 || \
369 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000370static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
371{
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
373 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000374}
375static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
376{
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
378 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000379}
380static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
381{
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
383 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000384}
385static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
386{
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
388 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000389}
390#endif /* __clang__ etc */
391
392static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000394{
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
396 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
397 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
398 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000399
400 size_t processed = 0;
401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 for (;
403 len >= SHA512_BLOCK_SIZE;
404 processed += SHA512_BLOCK_SIZE,
405 msg += SHA512_BLOCK_SIZE,
406 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000407 uint64x2_t initial_sum, sum, intermed;
408
409 uint64x2_t ab_orig = ab;
410 uint64x2_t cd_orig = cd;
411 uint64x2_t ef_orig = ef;
412 uint64x2_t gh_orig = gh;
413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
415 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
416 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
417 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
418 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
419 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
420 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
421 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000422
423#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
425 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
426 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
427 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
428 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
429 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
430 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
431 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000432#endif
433
434 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
436 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
437 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
438 gh = vsha512h2q_u64(intermed, cd, ab);
439 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000440
441 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
443 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
444 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
445 ef = vsha512h2q_u64(intermed, ab, gh);
446 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000447
448 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
450 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
451 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
452 cd = vsha512h2q_u64(intermed, gh, ef);
453 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000454
455 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
457 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
458 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
459 ab = vsha512h2q_u64(intermed, ef, cd);
460 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000461
462 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
464 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
465 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
466 gh = vsha512h2q_u64(intermed, cd, ab);
467 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000468
469 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
471 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
472 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
473 ef = vsha512h2q_u64(intermed, ab, gh);
474 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000475
476 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
478 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
479 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
480 cd = vsha512h2q_u64(intermed, gh, ef);
481 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000482
483 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
485 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
486 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
487 ab = vsha512h2q_u64(intermed, ef, cd);
488 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000491 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
493 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
494 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
495 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
496 gh = vsha512h2q_u64(intermed, cd, ab);
497 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000498
499 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
501 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
502 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
503 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
504 ef = vsha512h2q_u64(intermed, ab, gh);
505 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000506
507 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
509 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
510 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
511 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
512 cd = vsha512h2q_u64(intermed, gh, ef);
513 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000514
515 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
517 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
518 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
519 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
520 ab = vsha512h2q_u64(intermed, ef, cd);
521 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000522
523 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
525 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
526 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
527 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
528 gh = vsha512h2q_u64(intermed, cd, ab);
529 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000530
531 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
533 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
534 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
535 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
536 ef = vsha512h2q_u64(intermed, ab, gh);
537 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000538
539 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
541 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
542 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
543 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
544 cd = vsha512h2q_u64(intermed, gh, ef);
545 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000546
547 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
549 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
550 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
551 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
552 ab = vsha512h2q_u64(intermed, ef, cd);
553 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000554 }
555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 ab = vaddq_u64(ab, ab_orig);
557 cd = vaddq_u64(cd, cd_orig);
558 ef = vaddq_u64(ef, ef_orig);
559 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000560 }
561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 vst1q_u64(&ctx->state[0], ab);
563 vst1q_u64(&ctx->state[2], cd);
564 vst1q_u64(&ctx->state[4], ef);
565 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000568}
569
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100570#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
571/*
572 * This function is for internal use only if we are building both C and A64
573 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
574 */
575static
576#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100577int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
578 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000579{
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
581 SHA512_BLOCK_SIZE) ==
582 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000583}
584
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100585#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
586
Jerry Yu92fc5382023-02-16 11:17:11 +0800587#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800588#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800589#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800590#elif defined(__GNUC__)
591#pragma GCC pop_options
592#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800593#undef MBEDTLS_POP_TARGET_PRAGMA
594#endif
595
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000596
597#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
598#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
599#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
600#endif
601
602
603#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
604
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100605#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
606/*
607 * This function is for internal use only if we are building both C and A64
608 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
609 */
610static
611#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100612int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
613 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000614{
615 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200617 uint64_t temp1, temp2, W[80];
618 uint64_t A[8];
619 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621#define SHR(x, n) ((x) >> (n))
622#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
624#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100625#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
628#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
631#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200634 do \
635 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
637 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200638 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200642 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200644
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200645#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 for (i = 0; i < 80; i++) {
647 if (i < 16) {
648 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
649 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200650 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200652 }
653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
655 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200656
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200657 local.temp1 = local.A[7]; local.A[7] = local.A[6];
658 local.A[6] = local.A[5]; local.A[5] = local.A[4];
659 local.A[4] = local.A[3]; local.A[3] = local.A[2];
660 local.A[2] = local.A[1]; local.A[1] = local.A[0];
661 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200662 }
663#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 for (i = 0; i < 16; i++) {
665 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 }
667
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200669 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000671 }
672
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 do {
675 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
676 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
677 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
678 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
679 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
680 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
681 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
682 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
683 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
684 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
685 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
686 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
687 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
688 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
689 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
690 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
691 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200692#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200695 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100697
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200698 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100700
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000702}
Jaeden Amero041039f2018-02-19 15:28:08 +0000703
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000704#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
705
706
707#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
708
709static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000711{
712 size_t processed = 0;
713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 while (len >= SHA512_BLOCK_SIZE) {
715 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
716 return 0;
717 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000718
719 data += SHA512_BLOCK_SIZE;
720 len -= SHA512_BLOCK_SIZE;
721
722 processed += SHA512_BLOCK_SIZE;
723 }
724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000726}
727
728#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
729
730
731#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
732
Gilles Peskine449bd832023-01-11 14:50:10 +0100733static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000734{
735 static int done = 0;
736 static int supported = 0;
737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000739 supported = mbedtls_a64_crypto_sha512_determine_support();
740 done = 1;
741 }
742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000744}
745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
747 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000748{
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 if (mbedtls_a64_crypto_sha512_has_support()) {
750 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
751 } else {
752 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
753 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000754}
755
Gilles Peskine449bd832023-01-11 14:50:10 +0100756int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
757 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000758{
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if (mbedtls_a64_crypto_sha512_has_support()) {
760 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
761 } else {
762 return mbedtls_internal_sha512_process_c(ctx, data);
763 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000764}
765
766#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000767
768/*
769 * SHA-512 process buffer
770 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100771int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
772 const unsigned char *input,
773 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000774{
Janos Follath24eed8d2019-11-22 13:21:35 +0000775 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000776 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000777 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 if (ilen == 0) {
780 return 0;
781 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000782
Paul Bakkerb8213a12011-07-11 08:16:18 +0000783 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000784 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
Paul Bakker5c2364c2012-10-01 14:41:15 +0000786 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000787
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000789 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 if (left && ilen >= fill) {
793 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
796 return ret;
797 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100798
Paul Bakker5121ce52009-01-03 21:22:43 +0000799 input += fill;
800 ilen -= fill;
801 left = 0;
802 }
803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000805 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 mbedtls_internal_sha512_process_many(ctx, input, ilen);
807 if (processed < SHA512_BLOCK_SIZE) {
808 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
809 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100810
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000811 input += processed;
812 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000813 }
814
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 if (ilen > 0) {
816 memcpy((void *) (ctx->buffer + left), input, ilen);
817 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100818
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000820}
821
Paul Bakker5121ce52009-01-03 21:22:43 +0000822/*
823 * SHA-512 final digest
824 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100825int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
826 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000827{
Janos Follath24eed8d2019-11-22 13:21:35 +0000828 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200829 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000830 uint64_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100831 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000832
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200833 /*
834 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
835 */
836 used = ctx->total[0] & 0x7F;
837
838 ctx->buffer[used++] = 0x80;
839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200841 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 memset(ctx->buffer + used, 0, 112 - used);
843 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200844 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100848 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200852 }
853
854 /*
855 * Add message length
856 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 high = (ctx->total[0] >> 61)
858 | (ctx->total[1] << 3);
859 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 sha512_put_uint64_be(high, ctx->buffer, 112);
862 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100865 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000867
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200868 /*
869 * Output final state
870 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 sha512_put_uint64_be(ctx->state[0], output, 0);
872 sha512_put_uint64_be(ctx->state[1], output, 8);
873 sha512_put_uint64_be(ctx->state[2], output, 16);
874 sha512_put_uint64_be(ctx->state[3], output, 24);
875 sha512_put_uint64_be(ctx->state[4], output, 32);
876 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000877
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200878#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100879 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200880#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 if (!truncated) {
882 sha512_put_uint64_be(ctx->state[6], output, 48);
883 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000884 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100885
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100886 ret = 0;
887
888exit:
889 mbedtls_sha512_free(ctx);
890 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000891}
892
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200894
Paul Bakker5121ce52009-01-03 21:22:43 +0000895/*
896 * output = SHA-512( input buffer )
897 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100898int mbedtls_sha512(const unsigned char *input,
899 size_t ilen,
900 unsigned char *output,
901 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000902{
Janos Follath24eed8d2019-11-22 13:21:35 +0000903 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000905
Valerio Setti43363f52022-12-14 08:53:23 +0100906#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100908 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 }
Valerio Setti43363f52022-12-14 08:53:23 +0100910#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100912 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 }
Valerio Setti43363f52022-12-14 08:53:23 +0100914#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100916 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100918#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000919
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100923 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100925
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100927 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100931 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100933
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100934exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000938}
939
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
942/*
943 * FIPS-180-2 test vectors
944 */
Valerio Setti43363f52022-12-14 08:53:23 +0100945static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000946{
947 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 {
949 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
950 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000951 { "" }
952};
953
Valerio Setti43363f52022-12-14 08:53:23 +0100954static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000955{
956 3, 112, 1000
957};
958
Valerio Setti43363f52022-12-14 08:53:23 +0100959typedef const unsigned char (sha_test_sum_t)[64];
960
961/*
962 * SHA-384 test vectors
963 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200964#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100965static sha_test_sum_t sha384_test_sum[] =
966{
Paul Bakker5121ce52009-01-03 21:22:43 +0000967 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
968 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
969 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
970 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
971 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
972 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
973 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
974 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
975 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
976 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
977 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
978 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
979 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
980 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
981 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
982 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
983 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100984 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
985};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200986#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000987
Valerio Setti43363f52022-12-14 08:53:23 +0100988/*
989 * SHA-512 test vectors
990 */
991#if defined(MBEDTLS_SHA512_C)
992static sha_test_sum_t sha512_test_sum[] =
993{
Paul Bakker5121ce52009-01-03 21:22:43 +0000994 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
995 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
996 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
997 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
998 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
999 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
1000 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
1001 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
1002 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
1003 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
1004 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
1005 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
1006 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
1007 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
1008 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
1009 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
1010 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
1011 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1012 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1013 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1014 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1015 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1016 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1017 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1018};
Valerio Setti43363f52022-12-14 08:53:23 +01001019#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
Gilles Peskine449bd832023-01-11 14:50:10 +01001021static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001022{
Valerio Setti43363f52022-12-14 08:53:23 +01001023 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001024 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001025 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001027
Valerio Setti43363f52022-12-14 08:53:23 +01001028#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001030#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001032#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001034#endif
1035
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1037 if (NULL == buf) {
1038 if (verbose != 0) {
1039 mbedtls_printf("Buffer allocation failed\n");
1040 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001041
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001043 }
1044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001046
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 for (i = 0; i < 3; i++) {
1048 if (verbose != 0) {
1049 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1050 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001053 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001055
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 if (i == 2) {
1057 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001058
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 for (int j = 0; j < 1000; j++) {
1060 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1061 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001062 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 }
1064 }
1065 } else {
1066 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1067 sha_test_buflen[i]);
1068 if (ret != 0) {
1069 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001070 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001071 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001072
1073 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1074 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001075 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001076
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001078 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001079 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001080 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001081
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 if (verbose != 0) {
1083 mbedtls_printf("passed\n");
1084 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001085 }
1086
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 if (verbose != 0) {
1088 mbedtls_printf("\n");
1089 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001090
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001091 goto exit;
1092
1093fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 if (verbose != 0) {
1095 mbedtls_printf("failed\n");
1096 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001097
Paul Bakker5b4af392014-06-26 12:09:34 +02001098exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 mbedtls_sha512_free(&ctx);
1100 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001101
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001103}
1104
Valerio Setti898e7a32022-12-14 08:55:53 +01001105#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001106int mbedtls_sha512_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, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001109}
Valerio Setti898e7a32022-12-14 08:55:53 +01001110#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001111
Valerio Setti898e7a32022-12-14 08:55:53 +01001112#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001113int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001114{
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001116}
Valerio Setti898e7a32022-12-14 08:55:53 +01001117#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001118
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001119#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001122
Valerio Setti43363f52022-12-14 08:53:23 +01001123#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */