blob: 767857f344a8336ff689e42954a6b126cbd0ed27 [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
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Valerio Setti43363f52022-12-14 08:53:23 +010027#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000033#if defined(_MSC_VER) || defined(__WATCOMC__)
34 #define UL64(x) x##ui64
35#else
36 #define UL64(x) x##ULL
37#endif
38
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010042
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000043#if defined(__aarch64__)
44# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010045 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080046/* *INDENT-OFF* */
47/*
48 * Best performance comes from most recent compilers, with intrinsics and -O3.
49 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
50 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
51 *
52 * GCC < 8 won't work at all (lacks the sha512 instructions)
53 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
54 *
55 * Clang < 7 won't work at all (lacks the sha512 instructions)
56 * Clang 7-12 don't have intrinsics (but we work around that with inline
57 * assembler) or __ARM_FEATURE_SHA512
58 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
59 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
60 */
61#if !defined(__ARM_FEATURE_SHA512)
62 /* Test Clang first, as it defines __GNUC__ */
63# if defined(__clang__)
64# if __clang_major__ < 7
65# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
66# elif __clang_major__ < 13 || \
67 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0)
68 /* We implement the intrinsics with inline assembler, so don't error */
69# else
70# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
71# endif
72# elif defined(__GNUC__)
73# if __GNUC__ < 8
74# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
75# else
76# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
77# endif
78# else
79# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
80# endif
81#endif
82/* *INDENT-ON* */
83
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000084# include <arm_neon.h>
85# endif
86# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
87# if defined(__unix__)
88# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010089/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000090# include <sys/auxv.h>
91# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010092/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000093# include <signal.h>
94# endif
95# endif
96#elif defined(_M_ARM64)
97# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010098 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000099# include <arm64_neon.h>
100# endif
101#else
102# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
103# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
104#endif
105
106#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
107/*
108 * Capability detection code comes early, so we can disable
109 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
110 */
111#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100112static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000113{
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000115}
116#elif defined(__APPLE__)
117#include <sys/types.h>
118#include <sys/sysctl.h>
119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000121{
122 int value = 0;
123 size_t value_len = sizeof(value);
124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
126 NULL, 0);
127 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000128}
129#elif defined(_M_ARM64)
130/*
131 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
132 * available to pass to IsProcessorFeaturePresent() to check for
133 * SHA-512 support. So we fall back to the C code only.
134 */
135#if defined(_MSC_VER)
136#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
137#else
138#warning "No mechanism to detect A64_CRYPTO found, using C code only"
139#endif
140#elif defined(__unix__) && defined(SIG_SETMASK)
141/* Detection with SIGILL, setjmp() and longjmp() */
142#include <signal.h>
143#include <setjmp.h>
144
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000145static jmp_buf return_from_sigill;
146
147/*
148 * A64 SHA512 support detection via SIGILL
149 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100150static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000151{
152 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000154}
155
Gilles Peskine449bd832023-01-11 14:50:10 +0100156static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000157{
158 struct sigaction old_action, new_action;
159
160 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 if (sigprocmask(0, NULL, &old_mask)) {
162 return 0;
163 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000166 new_action.sa_flags = 0;
167 new_action.sa_handler = sigill_handler;
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000170
171 static int ret = 0;
172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000174 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000176 ret = 1;
177 }
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 sigaction(SIGILL, &old_action, NULL);
180 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000183}
184#else
185#warning "No mechanism to detect A64_CRYPTO found, using C code only"
186#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
187#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
188
189#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
190
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200191#if !defined(MBEDTLS_SHA512_ALT)
192
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000193#define SHA512_BLOCK_SIZE 128
194
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200195#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100196static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200197{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100198 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200199}
200#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100201#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200202#endif /* MBEDTLS_SHA512_SMALLER */
203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200205{
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200207}
208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200210{
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200212 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200214
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200216}
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
219 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200220{
221 *dst = *src;
222}
223
Paul Bakker5121ce52009-01-03 21:22:43 +0000224/*
225 * SHA-512 context setup
226 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100227int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000228{
Valerio Setti43363f52022-12-14 08:53:23 +0100229#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100231 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 }
Valerio Setti43363f52022-12-14 08:53:23 +0100233#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100235 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 }
Valerio Setti43363f52022-12-14 08:53:23 +0100237#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100239 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100241#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000242
Paul Bakker5121ce52009-01-03 21:22:43 +0000243 ctx->total[0] = 0;
244 ctx->total[1] = 0;
245
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100247#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000248 ctx->state[0] = UL64(0x6A09E667F3BCC908);
249 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
250 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
251 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
252 ctx->state[4] = UL64(0x510E527FADE682D1);
253 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
254 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
255 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100256#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100258#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000259 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
260 ctx->state[1] = UL64(0x629A292A367CD507);
261 ctx->state[2] = UL64(0x9159015A3070DD17);
262 ctx->state[3] = UL64(0x152FECD8F70E5939);
263 ctx->state[4] = UL64(0x67332667FFC00B31);
264 ctx->state[5] = UL64(0x8EB44A8768581511);
265 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
266 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200267#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000268 }
269
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200270#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200272#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000275}
276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200278
279/*
280 * Round constants
281 */
282static const uint64_t K[80] =
283{
284 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
285 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
286 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
287 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
288 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
289 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
290 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
291 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
292 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
293 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
294 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
295 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
296 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
297 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
298 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
299 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
300 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
301 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
302 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
303 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
304 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
305 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
306 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
307 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
308 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
309 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
310 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
311 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
312 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
313 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
314 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
315 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
316 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
317 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
318 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
319 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
320 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
321 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
322 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
323 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
324};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000325#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200326
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000327#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
328 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
329
330#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
331# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
332# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
333#endif
334
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000335/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
336 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
337 */
338
339#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 (__clang_major__ < 13 || \
341 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000342static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
343{
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
345 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000346}
347static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
348{
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
350 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000351}
352static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
353{
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
355 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000356}
357static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
358{
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
360 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000361}
362#endif /* __clang__ etc */
363
364static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000366{
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
368 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
369 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
370 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000371
372 size_t processed = 0;
373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 for (;
375 len >= SHA512_BLOCK_SIZE;
376 processed += SHA512_BLOCK_SIZE,
377 msg += SHA512_BLOCK_SIZE,
378 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000379 uint64x2_t initial_sum, sum, intermed;
380
381 uint64x2_t ab_orig = ab;
382 uint64x2_t cd_orig = cd;
383 uint64x2_t ef_orig = ef;
384 uint64x2_t gh_orig = gh;
385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
387 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
388 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
389 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
390 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
391 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
392 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
393 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000394
395#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
397 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
398 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
399 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
400 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
401 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
402 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
403 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000404#endif
405
406 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
408 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
409 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
410 gh = vsha512h2q_u64(intermed, cd, ab);
411 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000412
413 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
415 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
416 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
417 ef = vsha512h2q_u64(intermed, ab, gh);
418 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000419
420 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
422 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
423 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
424 cd = vsha512h2q_u64(intermed, gh, ef);
425 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000426
427 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
429 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
430 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
431 ab = vsha512h2q_u64(intermed, ef, cd);
432 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000433
434 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
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 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
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 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
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 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
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
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000463 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
465 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
466 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
467 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
468 gh = vsha512h2q_u64(intermed, cd, ab);
469 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000470
471 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
473 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
474 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
475 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
476 ef = vsha512h2q_u64(intermed, ab, gh);
477 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000478
479 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
481 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
482 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
483 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
484 cd = vsha512h2q_u64(intermed, gh, ef);
485 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000486
487 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
489 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
490 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
491 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
492 ab = vsha512h2q_u64(intermed, ef, cd);
493 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000494
495 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
497 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
498 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
499 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
500 gh = vsha512h2q_u64(intermed, cd, ab);
501 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000502
503 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
505 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
506 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
507 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
508 ef = vsha512h2q_u64(intermed, ab, gh);
509 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000510
511 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
513 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
514 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
515 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
516 cd = vsha512h2q_u64(intermed, gh, ef);
517 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000518
519 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
521 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
522 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
523 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
524 ab = vsha512h2q_u64(intermed, ef, cd);
525 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000526 }
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 ab = vaddq_u64(ab, ab_orig);
529 cd = vaddq_u64(cd, cd_orig);
530 ef = vaddq_u64(ef, ef_orig);
531 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000532 }
533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 vst1q_u64(&ctx->state[0], ab);
535 vst1q_u64(&ctx->state[2], cd);
536 vst1q_u64(&ctx->state[4], ef);
537 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000540}
541
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100542#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
543/*
544 * This function is for internal use only if we are building both C and A64
545 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
546 */
547static
548#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100549int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
550 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000551{
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
553 SHA512_BLOCK_SIZE) ==
554 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000555}
556
557#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
558
559
560#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
561#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
562#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
563#endif
564
565
566#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
567
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100568#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
569/*
570 * This function is for internal use only if we are building both C and A64
571 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
572 */
573static
574#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100575int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
576 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000577{
578 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200580 uint64_t temp1, temp2, W[80];
581 uint64_t A[8];
582 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584#define SHR(x, n) ((x) >> (n))
585#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000586
587#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100588#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000589
Gilles Peskine449bd832023-01-11 14:50:10 +0100590#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
591#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000592
Gilles Peskine449bd832023-01-11 14:50:10 +0100593#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
594#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200597 do \
598 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
600 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200601 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200605 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200607
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200608#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 for (i = 0; i < 80; i++) {
610 if (i < 16) {
611 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
612 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200613 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200615 }
616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
618 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200619
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200620 local.temp1 = local.A[7]; local.A[7] = local.A[6];
621 local.A[6] = local.A[5]; local.A[5] = local.A[4];
622 local.A[4] = local.A[3]; local.A[3] = local.A[2];
623 local.A[2] = local.A[1]; local.A[1] = local.A[0];
624 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200625 }
626#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 for (i = 0; i < 16; i++) {
628 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 }
630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200632 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 do {
638 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
639 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
640 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
641 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
642 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
643 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
644 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
645 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
646 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
647 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
648 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
649 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
650 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
651 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
652 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
653 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
654 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200655#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200658 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100660
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200661 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000665}
Jaeden Amero041039f2018-02-19 15:28:08 +0000666
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000667#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
668
669
670#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
671
672static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000674{
675 size_t processed = 0;
676
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 while (len >= SHA512_BLOCK_SIZE) {
678 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
679 return 0;
680 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000681
682 data += SHA512_BLOCK_SIZE;
683 len -= SHA512_BLOCK_SIZE;
684
685 processed += SHA512_BLOCK_SIZE;
686 }
687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000689}
690
691#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
692
693
694#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
695
Gilles Peskine449bd832023-01-11 14:50:10 +0100696static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000697{
698 static int done = 0;
699 static int supported = 0;
700
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000702 supported = mbedtls_a64_crypto_sha512_determine_support();
703 done = 1;
704 }
705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000707}
708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
710 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000711{
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 if (mbedtls_a64_crypto_sha512_has_support()) {
713 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
714 } else {
715 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
716 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000717}
718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
720 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000721{
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 if (mbedtls_a64_crypto_sha512_has_support()) {
723 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
724 } else {
725 return mbedtls_internal_sha512_process_c(ctx, data);
726 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000727}
728
729#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
731/*
732 * SHA-512 process buffer
733 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100734int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
735 const unsigned char *input,
736 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000737{
Janos Follath24eed8d2019-11-22 13:21:35 +0000738 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000739 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000740 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 if (ilen == 0) {
743 return 0;
744 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000745
Paul Bakkerb8213a12011-07-11 08:16:18 +0000746 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000747 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Paul Bakker5c2364c2012-10-01 14:41:15 +0000749 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000752 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000754
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 if (left && ilen >= fill) {
756 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100757
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
759 return ret;
760 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100761
Paul Bakker5121ce52009-01-03 21:22:43 +0000762 input += fill;
763 ilen -= fill;
764 left = 0;
765 }
766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000768 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 mbedtls_internal_sha512_process_many(ctx, input, ilen);
770 if (processed < SHA512_BLOCK_SIZE) {
771 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
772 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100773
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000774 input += processed;
775 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000776 }
777
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 if (ilen > 0) {
779 memcpy((void *) (ctx->buffer + left), input, ilen);
780 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000783}
784
Paul Bakker5121ce52009-01-03 21:22:43 +0000785/*
786 * SHA-512 final digest
787 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
789 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000790{
Janos Follath24eed8d2019-11-22 13:21:35 +0000791 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200792 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000793 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000794
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200795 /*
796 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
797 */
798 used = ctx->total[0] & 0x7F;
799
800 ctx->buffer[used++] = 0x80;
801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200803 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 memset(ctx->buffer + used, 0, 112 - used);
805 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200806 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
810 return ret;
811 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200812
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200814 }
815
816 /*
817 * Add message length
818 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 high = (ctx->total[0] >> 61)
820 | (ctx->total[1] << 3);
821 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 sha512_put_uint64_be(high, ctx->buffer, 112);
824 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
827 return ret;
828 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000829
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200830 /*
831 * Output final state
832 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 sha512_put_uint64_be(ctx->state[0], output, 0);
834 sha512_put_uint64_be(ctx->state[1], output, 8);
835 sha512_put_uint64_be(ctx->state[2], output, 16);
836 sha512_put_uint64_be(ctx->state[3], output, 24);
837 sha512_put_uint64_be(ctx->state[4], output, 32);
838 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
David Horstmann2788f6b2022-10-06 18:45:09 +0100840 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200841#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100842 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200843#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 if (!truncated) {
845 sha512_put_uint64_be(ctx->state[6], output, 48);
846 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000847 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100848
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000850}
851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200853
Paul Bakker5121ce52009-01-03 21:22:43 +0000854/*
855 * output = SHA-512( input buffer )
856 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100857int mbedtls_sha512(const unsigned char *input,
858 size_t ilen,
859 unsigned char *output,
860 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000861{
Janos Follath24eed8d2019-11-22 13:21:35 +0000862 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000864
Valerio Setti43363f52022-12-14 08:53:23 +0100865#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100867 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 }
Valerio Setti43363f52022-12-14 08:53:23 +0100869#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100871 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 }
Valerio Setti43363f52022-12-14 08:53:23 +0100873#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100875 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100877#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100880
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100882 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100884
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100886 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100890 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100892
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100893exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000897}
898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
901/*
902 * FIPS-180-2 test vectors
903 */
Valerio Setti43363f52022-12-14 08:53:23 +0100904static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000905{
906 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 {
908 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
909 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000910 { "" }
911};
912
Valerio Setti43363f52022-12-14 08:53:23 +0100913static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000914{
915 3, 112, 1000
916};
917
Valerio Setti43363f52022-12-14 08:53:23 +0100918typedef const unsigned char (sha_test_sum_t)[64];
919
920/*
921 * SHA-384 test vectors
922 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200923#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100924static sha_test_sum_t sha384_test_sum[] =
925{
Paul Bakker5121ce52009-01-03 21:22:43 +0000926 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
927 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
928 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
929 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
930 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
931 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
932 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
933 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
934 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
935 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
936 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
937 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
938 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
939 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
940 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
941 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
942 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100943 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
944};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200945#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Valerio Setti43363f52022-12-14 08:53:23 +0100947/*
948 * SHA-512 test vectors
949 */
950#if defined(MBEDTLS_SHA512_C)
951static sha_test_sum_t sha512_test_sum[] =
952{
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
954 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
955 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
956 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
957 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
958 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
959 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
960 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
961 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
962 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
963 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
964 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
965 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
966 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
967 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
968 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
969 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
970 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
971 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
972 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
973 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
974 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
975 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
976 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
977};
Valerio Setti43363f52022-12-14 08:53:23 +0100978#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000983{
Valerio Setti43363f52022-12-14 08:53:23 +0100984 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500985 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200986 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000988
Valerio Setti43363f52022-12-14 08:53:23 +0100989#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100991#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100993#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100995#endif
996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 buf = mbedtls_calloc(1024, sizeof(unsigned char));
998 if (NULL == buf) {
999 if (verbose != 0) {
1000 mbedtls_printf("Buffer allocation failed\n");
1001 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001004 }
1005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 for (i = 0; i < 3; i++) {
1009 if (verbose != 0) {
1010 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1011 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001012
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001014 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 if (i == 2) {
1018 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 for (int j = 0; j < 1000; j++) {
1021 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1022 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001023 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 }
1025 }
1026 } else {
1027 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1028 sha_test_buflen[i]);
1029 if (ret != 0) {
1030 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001031 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001033
1034 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1035 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001036 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001039 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001040 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001041 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 if (verbose != 0) {
1044 mbedtls_printf("passed\n");
1045 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001046 }
1047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 if (verbose != 0) {
1049 mbedtls_printf("\n");
1050 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001052 goto exit;
1053
1054fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 if (verbose != 0) {
1056 mbedtls_printf("failed\n");
1057 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001058
Paul Bakker5b4af392014-06-26 12:09:34 +02001059exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 mbedtls_sha512_free(&ctx);
1061 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001062
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001064}
1065
Valerio Setti898e7a32022-12-14 08:55:53 +01001066#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001067int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001068{
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001070}
Valerio Setti898e7a32022-12-14 08:55:53 +01001071#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001072
Valerio Setti898e7a32022-12-14 08:55:53 +01001073#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001074int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001075{
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001077}
Valerio Setti898e7a32022-12-14 08:55:53 +01001078#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001079
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001080#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001081
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001082#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001083
Valerio Setti43363f52022-12-14 08:53:23 +01001084#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */