blob: 827c08f34f1ad4f8c2ebea0b21870c7b14e41e0e [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 */
Jerry Yu64e5d4a2023-02-15 11:46:57 +080061# 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 && \
68 __clang_patchlevel__ == 0)
69 /* We implement the intrinsics with inline assembler, so don't error */
70# else
71# if __clang_major__ < 18
72 /* TODO: Re-consider above after https://reviews.llvm.org/D131064
73 * merged.
74 *
75 * The intrinsic declaration are guarded with ACLE predefined macros
76 * in clang, and those macros are only enabled with command line.
77 * Define the macros can enable those declaration and avoid compile
78 * error on it.
79 */
80# define __ARM_FEATURE_SHA512 1
81# endif
82# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
83# define MBEDTLS_POP_TARGET_PRAGMA
84# endif
85# elif defined(__GNUC__)
86# if __GNUC__ < 8
87# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
88# else
89# pragma GCC target ("arch=armv8.2-a+sha3")
90# endif
91# else
92# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
93# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080094# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080095/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000096# include <arm_neon.h>
97# endif
98# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
99# if defined(__unix__)
100# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100101/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000102# include <sys/auxv.h>
103# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100104/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000105# include <signal.h>
106# endif
107# endif
108#elif defined(_M_ARM64)
109# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000111# include <arm64_neon.h>
112# endif
113#else
114# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
115# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
116#endif
117
118#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
119/*
120 * Capability detection code comes early, so we can disable
121 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
122 */
123#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100124static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000125{
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000127}
128#elif defined(__APPLE__)
129#include <sys/types.h>
130#include <sys/sysctl.h>
131
Gilles Peskine449bd832023-01-11 14:50:10 +0100132static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000133{
134 int value = 0;
135 size_t value_len = sizeof(value);
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
138 NULL, 0);
139 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000140}
141#elif defined(_M_ARM64)
142/*
143 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
144 * available to pass to IsProcessorFeaturePresent() to check for
145 * SHA-512 support. So we fall back to the C code only.
146 */
147#if defined(_MSC_VER)
148#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
149#else
150#warning "No mechanism to detect A64_CRYPTO found, using C code only"
151#endif
152#elif defined(__unix__) && defined(SIG_SETMASK)
153/* Detection with SIGILL, setjmp() and longjmp() */
154#include <signal.h>
155#include <setjmp.h>
156
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000157static jmp_buf return_from_sigill;
158
159/*
160 * A64 SHA512 support detection via SIGILL
161 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100162static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000163{
164 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100165 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000166}
167
Gilles Peskine449bd832023-01-11 14:50:10 +0100168static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000169{
170 struct sigaction old_action, new_action;
171
172 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 if (sigprocmask(0, NULL, &old_mask)) {
174 return 0;
175 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000178 new_action.sa_flags = 0;
179 new_action.sa_handler = sigill_handler;
180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000182
183 static int ret = 0;
184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000186 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000188 ret = 1;
189 }
190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 sigaction(SIGILL, &old_action, NULL);
192 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000195}
196#else
197#warning "No mechanism to detect A64_CRYPTO found, using C code only"
198#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
199#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
200
201#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
202
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200203#if !defined(MBEDTLS_SHA512_ALT)
204
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000205#define SHA512_BLOCK_SIZE 128
206
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200207#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100208static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200209{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100210 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200211}
212#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100213#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200214#endif /* MBEDTLS_SHA512_SMALLER */
215
Gilles Peskine449bd832023-01-11 14:50:10 +0100216void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200217{
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200219}
220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200222{
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200224 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200226
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200228}
229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
231 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200232{
233 *dst = *src;
234}
235
Paul Bakker5121ce52009-01-03 21:22:43 +0000236/*
237 * SHA-512 context setup
238 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100239int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000240{
Valerio Setti43363f52022-12-14 08:53:23 +0100241#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100243 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 }
Valerio Setti43363f52022-12-14 08:53:23 +0100245#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100247 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 }
Valerio Setti43363f52022-12-14 08:53:23 +0100249#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100251 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100253#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000254
Paul Bakker5121ce52009-01-03 21:22:43 +0000255 ctx->total[0] = 0;
256 ctx->total[1] = 0;
257
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100259#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000260 ctx->state[0] = UL64(0x6A09E667F3BCC908);
261 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
262 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
263 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
264 ctx->state[4] = UL64(0x510E527FADE682D1);
265 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
266 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
267 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100268#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100270#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
272 ctx->state[1] = UL64(0x629A292A367CD507);
273 ctx->state[2] = UL64(0x9159015A3070DD17);
274 ctx->state[3] = UL64(0x152FECD8F70E5939);
275 ctx->state[4] = UL64(0x67332667FFC00B31);
276 ctx->state[5] = UL64(0x8EB44A8768581511);
277 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
278 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200279#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 }
281
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200282#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200284#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000287}
288
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200290
291/*
292 * Round constants
293 */
294static const uint64_t K[80] =
295{
296 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
297 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
298 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
299 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
300 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
301 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
302 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
303 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
304 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
305 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
306 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
307 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
308 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
309 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
310 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
311 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
312 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
313 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
314 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
315 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
316 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
317 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
318 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
319 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
320 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
321 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
322 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
323 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
324 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
325 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
326 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
327 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
328 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
329 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
330 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
331 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
332 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
333 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
334 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
335 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
336};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000337#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200338
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000339#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
340 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
341
342#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
343# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
344# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
345#endif
346
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000347/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
348 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
349 */
350
351#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 (__clang_major__ < 13 || \
353 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000354static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
355{
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
357 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000358}
359static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
360{
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
362 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000363}
364static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
365{
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
367 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000368}
369static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
370{
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
372 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000373}
374#endif /* __clang__ etc */
375
376static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000378{
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
380 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
381 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
382 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000383
384 size_t processed = 0;
385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 for (;
387 len >= SHA512_BLOCK_SIZE;
388 processed += SHA512_BLOCK_SIZE,
389 msg += SHA512_BLOCK_SIZE,
390 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000391 uint64x2_t initial_sum, sum, intermed;
392
393 uint64x2_t ab_orig = ab;
394 uint64x2_t cd_orig = cd;
395 uint64x2_t ef_orig = ef;
396 uint64x2_t gh_orig = gh;
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
399 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
400 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
401 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
402 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
403 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
404 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
405 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000406
407#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
409 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
410 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
411 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
412 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
413 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
414 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
415 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000416#endif
417
418 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
420 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
421 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
422 gh = vsha512h2q_u64(intermed, cd, ab);
423 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000424
425 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
427 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
428 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
429 ef = vsha512h2q_u64(intermed, ab, gh);
430 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000431
432 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
434 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
435 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
436 cd = vsha512h2q_u64(intermed, gh, ef);
437 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000438
439 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
441 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
442 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
443 ab = vsha512h2q_u64(intermed, ef, cd);
444 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000445
446 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
448 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
449 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
450 gh = vsha512h2q_u64(intermed, cd, ab);
451 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000452
453 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
455 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
456 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
457 ef = vsha512h2q_u64(intermed, ab, gh);
458 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000459
460 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
462 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
463 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
464 cd = vsha512h2q_u64(intermed, gh, ef);
465 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000466
467 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
469 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
470 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
471 ab = vsha512h2q_u64(intermed, ef, cd);
472 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000475 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
477 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
478 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
479 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
480 gh = vsha512h2q_u64(intermed, cd, ab);
481 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000482
483 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
485 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
486 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
487 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
488 ef = vsha512h2q_u64(intermed, ab, gh);
489 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000490
491 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
493 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
494 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
495 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
496 cd = vsha512h2q_u64(intermed, gh, ef);
497 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000498
499 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
501 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
502 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
503 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
504 ab = vsha512h2q_u64(intermed, ef, cd);
505 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000506
507 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
509 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
510 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
511 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
512 gh = vsha512h2q_u64(intermed, cd, ab);
513 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000514
515 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
517 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
518 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
519 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
520 ef = vsha512h2q_u64(intermed, ab, gh);
521 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000522
523 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
525 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
526 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
527 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
528 cd = vsha512h2q_u64(intermed, gh, ef);
529 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000530
531 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
533 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
534 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
535 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
536 ab = vsha512h2q_u64(intermed, ef, cd);
537 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000538 }
539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 ab = vaddq_u64(ab, ab_orig);
541 cd = vaddq_u64(cd, cd_orig);
542 ef = vaddq_u64(ef, ef_orig);
543 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000544 }
545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 vst1q_u64(&ctx->state[0], ab);
547 vst1q_u64(&ctx->state[2], cd);
548 vst1q_u64(&ctx->state[4], ef);
549 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000552}
553
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100554#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
555/*
556 * This function is for internal use only if we are building both C and A64
557 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
558 */
559static
560#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100561int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
562 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000563{
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
565 SHA512_BLOCK_SIZE) ==
566 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000567}
568
Jerry Yu92fc5382023-02-16 11:17:11 +0800569#if defined(MBEDTLS_POP_TARGET_PRAGMA)
570#pragma clang attribute pop
571#undef MBEDTLS_POP_TARGET_PRAGMA
572#endif
573
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000574#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
575
576
577#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
578#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
579#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
580#endif
581
582
583#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
584
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100585#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
586/*
587 * This function is for internal use only if we are building both C and A64
588 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
589 */
590static
591#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100592int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
593 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000594{
595 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200597 uint64_t temp1, temp2, W[80];
598 uint64_t A[8];
599 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601#define SHR(x, n) ((x) >> (n))
602#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
604#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100605#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
608#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
611#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200614 do \
615 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
617 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200618 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200622 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200624
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200625#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 for (i = 0; i < 80; i++) {
627 if (i < 16) {
628 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
629 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200630 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200632 }
633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
635 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200636
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200637 local.temp1 = local.A[7]; local.A[7] = local.A[6];
638 local.A[6] = local.A[5]; local.A[5] = local.A[4];
639 local.A[4] = local.A[3]; local.A[3] = local.A[2];
640 local.A[2] = local.A[1]; local.A[1] = local.A[0];
641 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200642 }
643#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 for (i = 0; i < 16; i++) {
645 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 }
647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200649 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 }
652
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 do {
655 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
656 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
657 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
658 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
659 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
660 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
661 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
662 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
663 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
664 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
665 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
666 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
667 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
668 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
669 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
670 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
671 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200672#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200675 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100677
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200678 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100680
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000682}
Jaeden Amero041039f2018-02-19 15:28:08 +0000683
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000684#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
685
686
687#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
688
689static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000691{
692 size_t processed = 0;
693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 while (len >= SHA512_BLOCK_SIZE) {
695 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
696 return 0;
697 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000698
699 data += SHA512_BLOCK_SIZE;
700 len -= SHA512_BLOCK_SIZE;
701
702 processed += SHA512_BLOCK_SIZE;
703 }
704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000706}
707
708#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
709
710
711#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000714{
715 static int done = 0;
716 static int supported = 0;
717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000719 supported = mbedtls_a64_crypto_sha512_determine_support();
720 done = 1;
721 }
722
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000724}
725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
727 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000728{
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 if (mbedtls_a64_crypto_sha512_has_support()) {
730 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
731 } else {
732 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
733 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000734}
735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
737 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000738{
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 if (mbedtls_a64_crypto_sha512_has_support()) {
740 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
741 } else {
742 return mbedtls_internal_sha512_process_c(ctx, data);
743 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000744}
745
746#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000747
748/*
749 * SHA-512 process buffer
750 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100751int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
752 const unsigned char *input,
753 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000754{
Janos Follath24eed8d2019-11-22 13:21:35 +0000755 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000756 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000757 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if (ilen == 0) {
760 return 0;
761 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000762
Paul Bakkerb8213a12011-07-11 08:16:18 +0000763 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000764 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000765
Paul Bakker5c2364c2012-10-01 14:41:15 +0000766 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000769 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if (left && ilen >= fill) {
773 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
776 return ret;
777 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100778
Paul Bakker5121ce52009-01-03 21:22:43 +0000779 input += fill;
780 ilen -= fill;
781 left = 0;
782 }
783
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000785 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 mbedtls_internal_sha512_process_many(ctx, input, ilen);
787 if (processed < SHA512_BLOCK_SIZE) {
788 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
789 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100790
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000791 input += processed;
792 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000793 }
794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 if (ilen > 0) {
796 memcpy((void *) (ctx->buffer + left), input, ilen);
797 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000800}
801
Paul Bakker5121ce52009-01-03 21:22:43 +0000802/*
803 * SHA-512 final digest
804 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100805int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
806 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000807{
Janos Follath24eed8d2019-11-22 13:21:35 +0000808 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200809 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000810 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000811
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200812 /*
813 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
814 */
815 used = ctx->total[0] & 0x7F;
816
817 ctx->buffer[used++] = 0x80;
818
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200820 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 memset(ctx->buffer + used, 0, 112 - used);
822 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200823 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
827 return ret;
828 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200831 }
832
833 /*
834 * Add message length
835 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 high = (ctx->total[0] >> 61)
837 | (ctx->total[1] << 3);
838 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 sha512_put_uint64_be(high, ctx->buffer, 112);
841 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000842
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
844 return ret;
845 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000846
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200847 /*
848 * Output final state
849 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 sha512_put_uint64_be(ctx->state[0], output, 0);
851 sha512_put_uint64_be(ctx->state[1], output, 8);
852 sha512_put_uint64_be(ctx->state[2], output, 16);
853 sha512_put_uint64_be(ctx->state[3], output, 24);
854 sha512_put_uint64_be(ctx->state[4], output, 32);
855 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000856
David Horstmann2788f6b2022-10-06 18:45:09 +0100857 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200858#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100859 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200860#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 if (!truncated) {
862 sha512_put_uint64_be(ctx->state[6], output, 48);
863 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000864 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000867}
868
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200870
Paul Bakker5121ce52009-01-03 21:22:43 +0000871/*
872 * output = SHA-512( input buffer )
873 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100874int mbedtls_sha512(const unsigned char *input,
875 size_t ilen,
876 unsigned char *output,
877 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000878{
Janos Follath24eed8d2019-11-22 13:21:35 +0000879 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200880 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000881
Valerio Setti43363f52022-12-14 08:53:23 +0100882#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100884 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 }
Valerio Setti43363f52022-12-14 08:53:23 +0100886#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100888 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 }
Valerio Setti43363f52022-12-14 08:53:23 +0100890#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100892 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100894#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100899 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100903 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100907 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100909
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100910exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000914}
915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
918/*
919 * FIPS-180-2 test vectors
920 */
Valerio Setti43363f52022-12-14 08:53:23 +0100921static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000922{
923 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 {
925 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
926 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 { "" }
928};
929
Valerio Setti43363f52022-12-14 08:53:23 +0100930static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000931{
932 3, 112, 1000
933};
934
Valerio Setti43363f52022-12-14 08:53:23 +0100935typedef const unsigned char (sha_test_sum_t)[64];
936
937/*
938 * SHA-384 test vectors
939 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200940#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100941static sha_test_sum_t sha384_test_sum[] =
942{
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
944 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
945 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
946 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
947 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
948 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
949 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
950 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
951 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
952 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
953 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
954 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
955 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
956 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
957 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
958 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
959 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100960 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
961};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200962#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000963
Valerio Setti43363f52022-12-14 08:53:23 +0100964/*
965 * SHA-512 test vectors
966 */
967#if defined(MBEDTLS_SHA512_C)
968static sha_test_sum_t sha512_test_sum[] =
969{
Paul Bakker5121ce52009-01-03 21:22:43 +0000970 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
971 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
972 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
973 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
974 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
975 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
976 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
977 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
978 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
979 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
980 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
981 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
982 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
983 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
984 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
985 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
986 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
987 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
988 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
989 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
990 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
991 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
992 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
993 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
994};
Valerio Setti43363f52022-12-14 08:53:23 +0100995#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001000{
Valerio Setti43363f52022-12-14 08:53:23 +01001001 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001002 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001003 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001005
Valerio Setti43363f52022-12-14 08:53:23 +01001006#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001008#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001010#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001012#endif
1013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1015 if (NULL == buf) {
1016 if (verbose != 0) {
1017 mbedtls_printf("Buffer allocation failed\n");
1018 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001021 }
1022
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 for (i = 0; i < 3; i++) {
1026 if (verbose != 0) {
1027 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1028 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001031 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 if (i == 2) {
1035 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001036
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 for (int j = 0; j < 1000; j++) {
1038 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1039 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001040 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 }
1042 }
1043 } else {
1044 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1045 sha_test_buflen[i]);
1046 if (ret != 0) {
1047 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001048 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001049 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001050
1051 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1052 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001053 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001056 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001057 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001058 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 if (verbose != 0) {
1061 mbedtls_printf("passed\n");
1062 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 }
1064
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 if (verbose != 0) {
1066 mbedtls_printf("\n");
1067 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001068
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001069 goto exit;
1070
1071fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 if (verbose != 0) {
1073 mbedtls_printf("failed\n");
1074 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001075
Paul Bakker5b4af392014-06-26 12:09:34 +02001076exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 mbedtls_sha512_free(&ctx);
1078 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001081}
1082
Valerio Setti898e7a32022-12-14 08:55:53 +01001083#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001084int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001085{
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001087}
Valerio Setti898e7a32022-12-14 08:55:53 +01001088#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001089
Valerio Setti898e7a32022-12-14 08:55:53 +01001090#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001091int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001092{
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001094}
Valerio Setti898e7a32022-12-14 08:55:53 +01001095#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001096
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001097#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001098
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001099#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001100
Valerio Setti43363f52022-12-14 08:53:23 +01001101#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */