blob: 919cf2041035bd61531abb245351aab001f0fc61 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Jerry Yua135dee2023-02-16 16:56:22 +080025#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
26 defined(__clang__) && __clang_major__ < 18 && \
27 __clang_major__ >= 13 && __clang_minor__ > 0 && __clang_patchlevel__ > 0
28/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
29 *
30 * The intrinsic declaration are guarded with ACLE predefined macros in clang,
31 * and those macros are only enabled with command line. Define the macros can
32 * enable those declaration and avoid compile error on it.
Jerry Yu4d786a72023-02-22 11:01:07 +080033 *
34 * `arm_neon.h` might be included in any head files. On the top of this file, we
35 * can guarantee this workaround always work.
Jerry Yua135dee2023-02-16 16:56:22 +080036 */
37#define __ARM_FEATURE_SHA512 1
Jerry Yu4d786a72023-02-22 11:01:07 +080038#define NEED_TARGET_OPTIONS
Jerry Yua135dee2023-02-16 16:56:22 +080039#endif /* __aarch64__ && __clang__ &&
Jerry Yuba4ec242023-02-21 15:59:13 +080040 !__ARM_FEATURE_SHA512 && __clang_major__ < 18 &&
41 __clang_major__ >= 13 && __clang_minor__ > 0 &&
42 __clang_patchlevel__ > 0 */
Jerry Yua135dee2023-02-16 16:56:22 +080043
Gilles Peskinedb09ef62020-06-03 01:43:33 +020044#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Jerry Yua135dee2023-02-16 16:56:22 +080046#if defined(MBEDTLS_POP_TARGET_PRAGMA) && \
47 !(defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Jerry Yuba4ec242023-02-21 15:59:13 +080048 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY))
Jerry Yua135dee2023-02-16 16:56:22 +080049#if defined(__clang__)
50#pragma clang attribute pop
51#endif
52#undef MBEDTLS_POP_TARGET_PRAGMA
53#endif
54
Valerio Setti43363f52022-12-14 08:53:23 +010055#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000056
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000057#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050058#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000059#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000060
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000061#if defined(_MSC_VER) || defined(__WATCOMC__)
62 #define UL64(x) x##ui64
63#else
64 #define UL64(x) x##ULL
65#endif
66
Rich Evans00ab4702015-02-06 13:43:58 +000067#include <string.h>
68
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000069#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010070
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000071#if defined(__aarch64__)
72# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010073 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080074/* *INDENT-OFF* */
75/*
76 * Best performance comes from most recent compilers, with intrinsics and -O3.
77 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
78 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
79 *
80 * GCC < 8 won't work at all (lacks the sha512 instructions)
81 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
82 *
83 * Clang < 7 won't work at all (lacks the sha512 instructions)
84 * Clang 7-12 don't have intrinsics (but we work around that with inline
85 * assembler) or __ARM_FEATURE_SHA512
86 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
87 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
88 */
Jerry Yu4d786a72023-02-22 11:01:07 +080089# if !defined(__ARM_FEATURE_SHA512) || defined(NEED_TARGET_OPTIONS)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080090 /* Test Clang first, as it defines __GNUC__ */
91# if defined(__clang__)
92# if __clang_major__ < 7
93# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
94# elif __clang_major__ < 13 || \
95 (__clang_major__ == 13 && __clang_minor__ == 0 && \
96 __clang_patchlevel__ == 0)
97 /* We implement the intrinsics with inline assembler, so don't error */
98# else
Jerry Yu64e5d4a2023-02-15 11:46:57 +080099# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
100# define MBEDTLS_POP_TARGET_PRAGMA
101# endif
102# elif defined(__GNUC__)
103# if __GNUC__ < 8
104# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
105# else
Jerry Yu2f2c0492023-02-16 14:24:46 +0800106# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800107# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +0800108# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800109# endif
110# else
111# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
112# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800113# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800114/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000115# include <arm_neon.h>
116# endif
117# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
118# if defined(__unix__)
119# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100120/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000121# include <sys/auxv.h>
122# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100123/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000124# include <signal.h>
125# endif
126# endif
127#elif defined(_M_ARM64)
128# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000130# include <arm64_neon.h>
131# endif
132#else
133# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
134# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
135#endif
136
137#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
138/*
139 * Capability detection code comes early, so we can disable
140 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
141 */
142#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100143static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000144{
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000146}
147#elif defined(__APPLE__)
148#include <sys/types.h>
149#include <sys/sysctl.h>
150
Gilles Peskine449bd832023-01-11 14:50:10 +0100151static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000152{
153 int value = 0;
154 size_t value_len = sizeof(value);
155
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
157 NULL, 0);
158 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000159}
160#elif defined(_M_ARM64)
161/*
162 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
163 * available to pass to IsProcessorFeaturePresent() to check for
164 * SHA-512 support. So we fall back to the C code only.
165 */
166#if defined(_MSC_VER)
167#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
168#else
169#warning "No mechanism to detect A64_CRYPTO found, using C code only"
170#endif
171#elif defined(__unix__) && defined(SIG_SETMASK)
172/* Detection with SIGILL, setjmp() and longjmp() */
173#include <signal.h>
174#include <setjmp.h>
175
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000176static jmp_buf return_from_sigill;
177
178/*
179 * A64 SHA512 support detection via SIGILL
180 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100181static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000182{
183 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000185}
186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000188{
189 struct sigaction old_action, new_action;
190
191 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 if (sigprocmask(0, NULL, &old_mask)) {
193 return 0;
194 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000197 new_action.sa_flags = 0;
198 new_action.sa_handler = sigill_handler;
199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000201
202 static int ret = 0;
203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000205 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000207 ret = 1;
208 }
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 sigaction(SIGILL, &old_action, NULL);
211 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000214}
215#else
216#warning "No mechanism to detect A64_CRYPTO found, using C code only"
217#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
218#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
219
220#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
221
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200222#if !defined(MBEDTLS_SHA512_ALT)
223
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000224#define SHA512_BLOCK_SIZE 128
225
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200226#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100227static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200228{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100229 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200230}
231#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100232#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200233#endif /* MBEDTLS_SHA512_SMALLER */
234
Gilles Peskine449bd832023-01-11 14:50:10 +0100235void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200236{
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200238}
239
Gilles Peskine449bd832023-01-11 14:50:10 +0100240void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200241{
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200243 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200245
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200247}
248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
250 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200251{
252 *dst = *src;
253}
254
Paul Bakker5121ce52009-01-03 21:22:43 +0000255/*
256 * SHA-512 context setup
257 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100258int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000259{
Valerio Setti43363f52022-12-14 08:53:23 +0100260#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100262 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 }
Valerio Setti43363f52022-12-14 08:53:23 +0100264#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100266 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 }
Valerio Setti43363f52022-12-14 08:53:23 +0100268#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100270 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100272#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000273
Paul Bakker5121ce52009-01-03 21:22:43 +0000274 ctx->total[0] = 0;
275 ctx->total[1] = 0;
276
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100278#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 ctx->state[0] = UL64(0x6A09E667F3BCC908);
280 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
281 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
282 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
283 ctx->state[4] = UL64(0x510E527FADE682D1);
284 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
285 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
286 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100287#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100289#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
291 ctx->state[1] = UL64(0x629A292A367CD507);
292 ctx->state[2] = UL64(0x9159015A3070DD17);
293 ctx->state[3] = UL64(0x152FECD8F70E5939);
294 ctx->state[4] = UL64(0x67332667FFC00B31);
295 ctx->state[5] = UL64(0x8EB44A8768581511);
296 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
297 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200298#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 }
300
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200301#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000302 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200303#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000306}
307
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200309
310/*
311 * Round constants
312 */
313static const uint64_t K[80] =
314{
315 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
316 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
317 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
318 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
319 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
320 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
321 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
322 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
323 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
324 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
325 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
326 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
327 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
328 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
329 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
330 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
331 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
332 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
333 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
334 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
335 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
336 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
337 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
338 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
339 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
340 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
341 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
342 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
343 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
344 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
345 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
346 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
347 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
348 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
349 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
350 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
351 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
352 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
353 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
354 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
355};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000356#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200357
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000358#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
359 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
360
361#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
362# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
363# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
364#endif
365
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000366/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
367 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
368 */
369
370#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 (__clang_major__ < 13 || \
372 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000373static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
374{
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
376 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000377}
378static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
379{
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
381 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000382}
383static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
384{
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
386 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000387}
388static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
389{
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
391 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000392}
393#endif /* __clang__ etc */
394
395static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000397{
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
399 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
400 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
401 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000402
403 size_t processed = 0;
404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 for (;
406 len >= SHA512_BLOCK_SIZE;
407 processed += SHA512_BLOCK_SIZE,
408 msg += SHA512_BLOCK_SIZE,
409 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000410 uint64x2_t initial_sum, sum, intermed;
411
412 uint64x2_t ab_orig = ab;
413 uint64x2_t cd_orig = cd;
414 uint64x2_t ef_orig = ef;
415 uint64x2_t gh_orig = gh;
416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
418 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
419 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
420 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
421 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
422 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
423 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
424 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000425
426#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
428 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
429 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
430 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
431 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
432 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
433 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
434 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000435#endif
436
437 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
439 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
440 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
441 gh = vsha512h2q_u64(intermed, cd, ab);
442 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000443
444 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
446 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
447 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
448 ef = vsha512h2q_u64(intermed, ab, gh);
449 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000450
451 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
453 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
454 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
455 cd = vsha512h2q_u64(intermed, gh, ef);
456 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000457
458 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
460 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
461 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
462 ab = vsha512h2q_u64(intermed, ef, cd);
463 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000464
465 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
467 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
468 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
469 gh = vsha512h2q_u64(intermed, cd, ab);
470 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000471
472 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
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 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
481 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
482 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
483 cd = vsha512h2q_u64(intermed, gh, ef);
484 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000485
486 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
488 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
489 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
490 ab = vsha512h2q_u64(intermed, ef, cd);
491 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000494 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
496 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
497 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
498 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
499 gh = vsha512h2q_u64(intermed, cd, ab);
500 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000501
502 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
504 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
505 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
506 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
507 ef = vsha512h2q_u64(intermed, ab, gh);
508 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000509
510 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
512 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
513 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
514 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
515 cd = vsha512h2q_u64(intermed, gh, ef);
516 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000517
518 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
520 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
521 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
522 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
523 ab = vsha512h2q_u64(intermed, ef, cd);
524 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000525
526 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
528 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
529 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
530 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
531 gh = vsha512h2q_u64(intermed, cd, ab);
532 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000533
534 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
536 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
537 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
538 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
539 ef = vsha512h2q_u64(intermed, ab, gh);
540 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000541
542 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
544 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
545 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
546 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
547 cd = vsha512h2q_u64(intermed, gh, ef);
548 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000549
550 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
552 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
553 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
554 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
555 ab = vsha512h2q_u64(intermed, ef, cd);
556 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000557 }
558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 ab = vaddq_u64(ab, ab_orig);
560 cd = vaddq_u64(cd, cd_orig);
561 ef = vaddq_u64(ef, ef_orig);
562 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000563 }
564
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 vst1q_u64(&ctx->state[0], ab);
566 vst1q_u64(&ctx->state[2], cd);
567 vst1q_u64(&ctx->state[4], ef);
568 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000571}
572
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100573#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
574/*
575 * This function is for internal use only if we are building both C and A64
576 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
577 */
578static
579#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100580int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
581 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000582{
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
584 SHA512_BLOCK_SIZE) ==
585 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000586}
587
Jerry Yu92fc5382023-02-16 11:17:11 +0800588#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800589#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800590#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800591#elif defined(__GNUC__)
592#pragma GCC pop_options
593#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800594#undef MBEDTLS_POP_TARGET_PRAGMA
595#endif
596
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000597#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
598
599
600#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
601#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
602#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
603#endif
604
605
606#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
607
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100608#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
609/*
610 * This function is for internal use only if we are building both C and A64
611 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
612 */
613static
614#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100615int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
616 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000617{
618 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200620 uint64_t temp1, temp2, W[80];
621 uint64_t A[8];
622 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624#define SHR(x, n) ((x) >> (n))
625#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
627#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100628#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
631#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
634#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200637 do \
638 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
640 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200641 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200645 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200647
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200648#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 for (i = 0; i < 80; i++) {
650 if (i < 16) {
651 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
652 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200653 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200655 }
656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
658 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200659
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200660 local.temp1 = local.A[7]; local.A[7] = local.A[6];
661 local.A[6] = local.A[5]; local.A[5] = local.A[4];
662 local.A[4] = local.A[3]; local.A[3] = local.A[2];
663 local.A[2] = local.A[1]; local.A[1] = local.A[0];
664 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200665 }
666#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 for (i = 0; i < 16; i++) {
668 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000669 }
670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200672 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 }
675
Paul Bakker5121ce52009-01-03 21:22:43 +0000676 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 do {
678 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
679 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
680 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
681 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
682 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
683 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
684 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
685 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
686 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
687 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
688 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
689 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
690 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
691 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
692 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
693 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
694 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200695#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200698 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100700
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200701 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100703
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000705}
Jaeden Amero041039f2018-02-19 15:28:08 +0000706
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000707#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
708
709
710#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
711
712static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000714{
715 size_t processed = 0;
716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 while (len >= SHA512_BLOCK_SIZE) {
718 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
719 return 0;
720 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000721
722 data += SHA512_BLOCK_SIZE;
723 len -= SHA512_BLOCK_SIZE;
724
725 processed += SHA512_BLOCK_SIZE;
726 }
727
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000729}
730
731#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
732
733
734#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000737{
738 static int done = 0;
739 static int supported = 0;
740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000742 supported = mbedtls_a64_crypto_sha512_determine_support();
743 done = 1;
744 }
745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000747}
748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
750 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000751{
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 if (mbedtls_a64_crypto_sha512_has_support()) {
753 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
754 } else {
755 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
756 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000757}
758
Gilles Peskine449bd832023-01-11 14:50:10 +0100759int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
760 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000761{
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 if (mbedtls_a64_crypto_sha512_has_support()) {
763 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
764 } else {
765 return mbedtls_internal_sha512_process_c(ctx, data);
766 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000767}
768
769#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000770
771/*
772 * SHA-512 process buffer
773 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100774int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
775 const unsigned char *input,
776 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000777{
Janos Follath24eed8d2019-11-22 13:21:35 +0000778 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000779 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000780 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 if (ilen == 0) {
783 return 0;
784 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
Paul Bakkerb8213a12011-07-11 08:16:18 +0000786 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000787 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000788
Paul Bakker5c2364c2012-10-01 14:41:15 +0000789 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000790
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 if (left && ilen >= fill) {
796 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100797
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
799 return ret;
800 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100801
Paul Bakker5121ce52009-01-03 21:22:43 +0000802 input += fill;
803 ilen -= fill;
804 left = 0;
805 }
806
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000808 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 mbedtls_internal_sha512_process_many(ctx, input, ilen);
810 if (processed < SHA512_BLOCK_SIZE) {
811 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
812 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100813
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000814 input += processed;
815 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000816 }
817
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 if (ilen > 0) {
819 memcpy((void *) (ctx->buffer + left), input, ilen);
820 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000823}
824
Paul Bakker5121ce52009-01-03 21:22:43 +0000825/*
826 * SHA-512 final digest
827 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100828int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
829 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000830{
Janos Follath24eed8d2019-11-22 13:21:35 +0000831 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200832 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000833 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000834
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200835 /*
836 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
837 */
838 used = ctx->total[0] & 0x7F;
839
840 ctx->buffer[used++] = 0x80;
841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200843 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 memset(ctx->buffer + used, 0, 112 - used);
845 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200846 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200848
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
850 return ret;
851 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200854 }
855
856 /*
857 * Add message length
858 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 high = (ctx->total[0] >> 61)
860 | (ctx->total[1] << 3);
861 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 sha512_put_uint64_be(high, ctx->buffer, 112);
864 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
867 return ret;
868 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200870 /*
871 * Output final state
872 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 sha512_put_uint64_be(ctx->state[0], output, 0);
874 sha512_put_uint64_be(ctx->state[1], output, 8);
875 sha512_put_uint64_be(ctx->state[2], output, 16);
876 sha512_put_uint64_be(ctx->state[3], output, 24);
877 sha512_put_uint64_be(ctx->state[4], output, 32);
878 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000879
David Horstmann2788f6b2022-10-06 18:45:09 +0100880 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200881#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100882 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200883#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if (!truncated) {
885 sha512_put_uint64_be(ctx->state[6], output, 48);
886 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000887 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000890}
891
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200893
Paul Bakker5121ce52009-01-03 21:22:43 +0000894/*
895 * output = SHA-512( input buffer )
896 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100897int mbedtls_sha512(const unsigned char *input,
898 size_t ilen,
899 unsigned char *output,
900 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000901{
Janos Follath24eed8d2019-11-22 13:21:35 +0000902 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000904
Valerio Setti43363f52022-12-14 08:53:23 +0100905#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100907 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 }
Valerio Setti43363f52022-12-14 08:53:23 +0100909#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100911 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 }
Valerio Setti43363f52022-12-14 08:53:23 +0100913#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100915 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100917#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100922 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100924
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100926 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100928
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100930 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100932
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100933exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100935
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000937}
938
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
941/*
942 * FIPS-180-2 test vectors
943 */
Valerio Setti43363f52022-12-14 08:53:23 +0100944static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000945{
946 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 {
948 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
949 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000950 { "" }
951};
952
Valerio Setti43363f52022-12-14 08:53:23 +0100953static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000954{
955 3, 112, 1000
956};
957
Valerio Setti43363f52022-12-14 08:53:23 +0100958typedef const unsigned char (sha_test_sum_t)[64];
959
960/*
961 * SHA-384 test vectors
962 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200963#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100964static sha_test_sum_t sha384_test_sum[] =
965{
Paul Bakker5121ce52009-01-03 21:22:43 +0000966 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
967 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
968 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
969 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
970 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
971 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
972 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
973 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
974 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
975 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
976 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
977 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
978 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
979 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
980 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
981 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
982 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100983 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
984};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200985#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000986
Valerio Setti43363f52022-12-14 08:53:23 +0100987/*
988 * SHA-512 test vectors
989 */
990#if defined(MBEDTLS_SHA512_C)
991static sha_test_sum_t sha512_test_sum[] =
992{
Paul Bakker5121ce52009-01-03 21:22:43 +0000993 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
994 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
995 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
996 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
997 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
998 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
999 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
1000 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
1001 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
1002 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
1003 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
1004 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
1005 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
1006 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
1007 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
1008 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
1009 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
1010 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1011 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1012 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1013 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1014 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1015 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1016 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1017};
Valerio Setti43363f52022-12-14 08:53:23 +01001018#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +02001021
Gilles Peskine449bd832023-01-11 14:50:10 +01001022static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001023{
Valerio Setti43363f52022-12-14 08:53:23 +01001024 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001025 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001026 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001028
Valerio Setti43363f52022-12-14 08:53:23 +01001029#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001031#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001033#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001035#endif
1036
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1038 if (NULL == buf) {
1039 if (verbose != 0) {
1040 mbedtls_printf("Buffer allocation failed\n");
1041 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001044 }
1045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 for (i = 0; i < 3; i++) {
1049 if (verbose != 0) {
1050 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1051 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001054 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001056
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 if (i == 2) {
1058 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 for (int j = 0; j < 1000; j++) {
1061 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1062 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001063 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 }
1065 }
1066 } else {
1067 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1068 sha_test_buflen[i]);
1069 if (ret != 0) {
1070 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001071 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001072 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001073
1074 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1075 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001076 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001077
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001079 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001080 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001081 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001082
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 if (verbose != 0) {
1084 mbedtls_printf("passed\n");
1085 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001086 }
1087
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 if (verbose != 0) {
1089 mbedtls_printf("\n");
1090 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001091
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001092 goto exit;
1093
1094fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 if (verbose != 0) {
1096 mbedtls_printf("failed\n");
1097 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001098
Paul Bakker5b4af392014-06-26 12:09:34 +02001099exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 mbedtls_sha512_free(&ctx);
1101 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001104}
1105
Valerio Setti898e7a32022-12-14 08:55:53 +01001106#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001107int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001108{
Gilles Peskine449bd832023-01-11 14:50:10 +01001109 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001110}
Valerio Setti898e7a32022-12-14 08:55:53 +01001111#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001112
Valerio Setti898e7a32022-12-14 08:55:53 +01001113#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001114int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001115{
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001117}
Valerio Setti898e7a32022-12-14 08:55:53 +01001118#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001119
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001120#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001122#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001123
Valerio Setti43363f52022-12-14 08:53:23 +01001124#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */