blob: 9f63cb977898c0a2502b43acc687a99a6aaff0fb [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Jerry Yua135dee2023-02-16 16:56:22 +080025#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
Jerry Yu7b4d9da2023-03-03 17:56:54 +080026 defined(__clang__) && __clang_major__ < 18 && __clang_major__ > 7
Jerry Yua135dee2023-02-16 16:56:22 +080027/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
28 *
Jerry Yufc2e1282023-02-27 11:16:56 +080029 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
30 * these are normally only enabled by the -march option on the command line.
31 * By defining the macros ourselves we gain access to those declarations without
32 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080033 *
Jerry Yufc2e1282023-02-27 11:16:56 +080034 * `arm_neon.h` could be included by any header file, so we put these defines
35 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080036 */
37#define __ARM_FEATURE_SHA512 1
Jerry Yu4d786a72023-02-22 11:01:07 +080038#define NEED_TARGET_OPTIONS
Jerry Yu7b4d9da2023-03-03 17:56:54 +080039#endif /* __aarch64__ && !__ARM_FEATURE_SHA512 &&
40 __clang__ && __clang_major__ < 18 && __clang_major__ > 7 */
Jerry Yua135dee2023-02-16 16:56:22 +080041
Gilles Peskinedb09ef62020-06-03 01:43:33 +020042#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000043
Valerio Setti43363f52022-12-14 08:53:23 +010044#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050047#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000048#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000049
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000050#if defined(_MSC_VER) || defined(__WATCOMC__)
51 #define UL64(x) x##ui64
52#else
53 #define UL64(x) x##ULL
54#endif
55
Rich Evans00ab4702015-02-06 13:43:58 +000056#include <string.h>
57
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000058#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010059
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000060#if defined(__aarch64__)
61# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010062 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080063/* *INDENT-OFF* */
64/*
65 * Best performance comes from most recent compilers, with intrinsics and -O3.
66 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
67 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
68 *
69 * GCC < 8 won't work at all (lacks the sha512 instructions)
70 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
71 *
72 * Clang < 7 won't work at all (lacks the sha512 instructions)
73 * Clang 7-12 don't have intrinsics (but we work around that with inline
74 * assembler) or __ARM_FEATURE_SHA512
75 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
76 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
77 */
Jerry Yu4d786a72023-02-22 11:01:07 +080078# if !defined(__ARM_FEATURE_SHA512) || defined(NEED_TARGET_OPTIONS)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080079 /* Test Clang first, as it defines __GNUC__ */
80# if defined(__clang__)
81# if __clang_major__ < 7
82# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080083# else
Jerry Yu64e5d4a2023-02-15 11:46:57 +080084# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
85# define MBEDTLS_POP_TARGET_PRAGMA
86# endif
87# elif defined(__GNUC__)
88# if __GNUC__ < 8
89# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
90# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080091# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080092# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +080093# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080094# endif
95# else
96# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
97# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080098# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080099/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000100# include <arm_neon.h>
101# endif
102# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
103# if defined(__unix__)
104# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100105/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000106# include <sys/auxv.h>
107# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100108/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000109# include <signal.h>
110# endif
111# endif
112#elif defined(_M_ARM64)
113# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000115# include <arm64_neon.h>
116# endif
117#else
118# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
119# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
120#endif
121
122#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
123/*
124 * Capability detection code comes early, so we can disable
125 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
126 */
127#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100128static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000129{
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000131}
132#elif defined(__APPLE__)
133#include <sys/types.h>
134#include <sys/sysctl.h>
135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000137{
138 int value = 0;
139 size_t value_len = sizeof(value);
140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
142 NULL, 0);
143 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000144}
145#elif defined(_M_ARM64)
146/*
147 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
148 * available to pass to IsProcessorFeaturePresent() to check for
149 * SHA-512 support. So we fall back to the C code only.
150 */
151#if defined(_MSC_VER)
152#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
153#else
154#warning "No mechanism to detect A64_CRYPTO found, using C code only"
155#endif
156#elif defined(__unix__) && defined(SIG_SETMASK)
157/* Detection with SIGILL, setjmp() and longjmp() */
158#include <signal.h>
159#include <setjmp.h>
160
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000161static jmp_buf return_from_sigill;
162
163/*
164 * A64 SHA512 support detection via SIGILL
165 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100166static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000167{
168 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000170}
171
Gilles Peskine449bd832023-01-11 14:50:10 +0100172static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000173{
174 struct sigaction old_action, new_action;
175
176 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 if (sigprocmask(0, NULL, &old_mask)) {
178 return 0;
179 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000182 new_action.sa_flags = 0;
183 new_action.sa_handler = sigill_handler;
184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000186
187 static int ret = 0;
188
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000190 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000192 ret = 1;
193 }
194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 sigaction(SIGILL, &old_action, NULL);
196 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000199}
200#else
201#warning "No mechanism to detect A64_CRYPTO found, using C code only"
202#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
203#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
204
205#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
206
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200207#if !defined(MBEDTLS_SHA512_ALT)
208
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000209#define SHA512_BLOCK_SIZE 128
210
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200211#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100212static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200213{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100214 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200215}
216#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100217#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200218#endif /* MBEDTLS_SHA512_SMALLER */
219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200221{
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200223}
224
Gilles Peskine449bd832023-01-11 14:50:10 +0100225void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200226{
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200228 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200232}
233
Gilles Peskine449bd832023-01-11 14:50:10 +0100234void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
235 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200236{
237 *dst = *src;
238}
239
Paul Bakker5121ce52009-01-03 21:22:43 +0000240/*
241 * SHA-512 context setup
242 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100243int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000244{
Valerio Setti43363f52022-12-14 08:53:23 +0100245#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 if (is384 != 0 && is384 != 1) {
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#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100251 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 }
Valerio Setti43363f52022-12-14 08:53:23 +0100253#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100255 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100257#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000258
Paul Bakker5121ce52009-01-03 21:22:43 +0000259 ctx->total[0] = 0;
260 ctx->total[1] = 0;
261
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100263#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000264 ctx->state[0] = UL64(0x6A09E667F3BCC908);
265 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
266 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
267 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
268 ctx->state[4] = UL64(0x510E527FADE682D1);
269 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
270 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
271 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100272#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100274#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000275 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
276 ctx->state[1] = UL64(0x629A292A367CD507);
277 ctx->state[2] = UL64(0x9159015A3070DD17);
278 ctx->state[3] = UL64(0x152FECD8F70E5939);
279 ctx->state[4] = UL64(0x67332667FFC00B31);
280 ctx->state[5] = UL64(0x8EB44A8768581511);
281 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
282 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200283#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 }
285
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200286#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200288#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000291}
292
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200293#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200294
295/*
296 * Round constants
297 */
298static const uint64_t K[80] =
299{
300 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
301 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
302 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
303 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
304 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
305 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
306 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
307 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
308 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
309 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
310 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
311 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
312 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
313 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
314 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
315 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
316 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
317 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
318 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
319 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
320 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
321 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
322 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
323 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
324 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
325 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
326 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
327 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
328 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
329 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
330 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
331 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
332 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
333 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
334 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
335 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
336 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
337 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
338 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
339 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
340};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000341#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200342
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000343#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
344 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
345
346#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
347# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
348# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
349#endif
350
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000351/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
352 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
353 */
354
355#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 (__clang_major__ < 13 || \
357 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000358static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
359{
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
361 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000362}
363static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
364{
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
366 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000367}
368static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
369{
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
371 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000372}
373static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
374{
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
376 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000377}
378#endif /* __clang__ etc */
379
380static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000382{
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
384 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
385 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
386 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000387
388 size_t processed = 0;
389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 for (;
391 len >= SHA512_BLOCK_SIZE;
392 processed += SHA512_BLOCK_SIZE,
393 msg += SHA512_BLOCK_SIZE,
394 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000395 uint64x2_t initial_sum, sum, intermed;
396
397 uint64x2_t ab_orig = ab;
398 uint64x2_t cd_orig = cd;
399 uint64x2_t ef_orig = ef;
400 uint64x2_t gh_orig = gh;
401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
403 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
404 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
405 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
406 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
407 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
408 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
409 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000410
411#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
413 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
414 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
415 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
416 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
417 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
418 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
419 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000420#endif
421
422 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
424 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
425 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
426 gh = vsha512h2q_u64(intermed, cd, ab);
427 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000428
429 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
431 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
432 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
433 ef = vsha512h2q_u64(intermed, ab, gh);
434 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000435
436 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
438 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
439 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
440 cd = vsha512h2q_u64(intermed, gh, ef);
441 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000442
443 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
445 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
446 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
447 ab = vsha512h2q_u64(intermed, ef, cd);
448 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000449
450 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
452 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
453 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
454 gh = vsha512h2q_u64(intermed, cd, ab);
455 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000456
457 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
459 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
460 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
461 ef = vsha512h2q_u64(intermed, ab, gh);
462 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000463
464 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
466 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
467 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
468 cd = vsha512h2q_u64(intermed, gh, ef);
469 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000470
471 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
473 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
474 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
475 ab = vsha512h2q_u64(intermed, ef, cd);
476 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000479 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
481 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
482 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
483 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
484 gh = vsha512h2q_u64(intermed, cd, ab);
485 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000486
487 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
489 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
490 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
491 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
492 ef = vsha512h2q_u64(intermed, ab, gh);
493 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000494
495 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
497 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
498 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
499 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
500 cd = vsha512h2q_u64(intermed, gh, ef);
501 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000502
503 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
505 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
506 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
507 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
508 ab = vsha512h2q_u64(intermed, ef, cd);
509 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000510
511 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
513 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
514 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
515 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
516 gh = vsha512h2q_u64(intermed, cd, ab);
517 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000518
519 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
521 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
522 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
523 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
524 ef = vsha512h2q_u64(intermed, ab, gh);
525 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000526
527 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
529 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
530 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
531 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
532 cd = vsha512h2q_u64(intermed, gh, ef);
533 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000534
535 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
537 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
538 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
539 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
540 ab = vsha512h2q_u64(intermed, ef, cd);
541 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000542 }
543
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 ab = vaddq_u64(ab, ab_orig);
545 cd = vaddq_u64(cd, cd_orig);
546 ef = vaddq_u64(ef, ef_orig);
547 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000548 }
549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 vst1q_u64(&ctx->state[0], ab);
551 vst1q_u64(&ctx->state[2], cd);
552 vst1q_u64(&ctx->state[4], ef);
553 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000556}
557
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100558#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
559/*
560 * This function is for internal use only if we are building both C and A64
561 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
562 */
563static
564#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100565int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
566 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000567{
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
569 SHA512_BLOCK_SIZE) ==
570 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000571}
572
Jerry Yu92fc5382023-02-16 11:17:11 +0800573#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800574#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800575#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800576#elif defined(__GNUC__)
577#pragma GCC pop_options
578#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800579#undef MBEDTLS_POP_TARGET_PRAGMA
580#endif
581
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000582#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
583
584
585#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
586#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
587#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
588#endif
589
590
591#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
592
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100593#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
594/*
595 * This function is for internal use only if we are building both C and A64
596 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
597 */
598static
599#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100600int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
601 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000602{
603 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200605 uint64_t temp1, temp2, W[80];
606 uint64_t A[8];
607 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
Gilles Peskine449bd832023-01-11 14:50:10 +0100609#define SHR(x, n) ((x) >> (n))
610#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100613#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
616#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
619#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200622 do \
623 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
625 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200626 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200630 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200632
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200633#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 for (i = 0; i < 80; i++) {
635 if (i < 16) {
636 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
637 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200638 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200640 }
641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
643 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200644
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200645 local.temp1 = local.A[7]; local.A[7] = local.A[6];
646 local.A[6] = local.A[5]; local.A[5] = local.A[4];
647 local.A[4] = local.A[3]; local.A[3] = local.A[2];
648 local.A[2] = local.A[1]; local.A[1] = local.A[0];
649 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200650 }
651#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 for (i = 0; i < 16; i++) {
653 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 }
655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200657 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000659 }
660
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 do {
663 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
664 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
665 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
666 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
667 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
668 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
669 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
670 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
671 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
672 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
673 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
674 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
675 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
676 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
677 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
678 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
679 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200680#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200683 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100685
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200686 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000690}
Jaeden Amero041039f2018-02-19 15:28:08 +0000691
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000692#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
693
694
695#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
696
697static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000699{
700 size_t processed = 0;
701
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 while (len >= SHA512_BLOCK_SIZE) {
703 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
704 return 0;
705 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000706
707 data += SHA512_BLOCK_SIZE;
708 len -= SHA512_BLOCK_SIZE;
709
710 processed += SHA512_BLOCK_SIZE;
711 }
712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000714}
715
716#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
717
718
719#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000722{
723 static int done = 0;
724 static int supported = 0;
725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000727 supported = mbedtls_a64_crypto_sha512_determine_support();
728 done = 1;
729 }
730
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000732}
733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
735 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000736{
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 if (mbedtls_a64_crypto_sha512_has_support()) {
738 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
739 } else {
740 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
741 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000742}
743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
745 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000746{
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 if (mbedtls_a64_crypto_sha512_has_support()) {
748 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
749 } else {
750 return mbedtls_internal_sha512_process_c(ctx, data);
751 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000752}
753
754#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000755
756/*
757 * SHA-512 process buffer
758 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100759int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
760 const unsigned char *input,
761 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000762{
Janos Follath24eed8d2019-11-22 13:21:35 +0000763 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000764 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000765 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 if (ilen == 0) {
768 return 0;
769 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000770
Paul Bakkerb8213a12011-07-11 08:16:18 +0000771 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000772 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000773
Paul Bakker5c2364c2012-10-01 14:41:15 +0000774 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000777 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 if (left && ilen >= fill) {
781 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100782
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
784 return ret;
785 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100786
Paul Bakker5121ce52009-01-03 21:22:43 +0000787 input += fill;
788 ilen -= fill;
789 left = 0;
790 }
791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000793 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 mbedtls_internal_sha512_process_many(ctx, input, ilen);
795 if (processed < SHA512_BLOCK_SIZE) {
796 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
797 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100798
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000799 input += processed;
800 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000801 }
802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 if (ilen > 0) {
804 memcpy((void *) (ctx->buffer + left), input, ilen);
805 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100806
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000808}
809
Paul Bakker5121ce52009-01-03 21:22:43 +0000810/*
811 * SHA-512 final digest
812 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100813int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
814 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000815{
Janos Follath24eed8d2019-11-22 13:21:35 +0000816 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200817 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000818 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000819
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200820 /*
821 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
822 */
823 used = ctx->total[0] & 0x7F;
824
825 ctx->buffer[used++] = 0x80;
826
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200828 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 memset(ctx->buffer + used, 0, 112 - used);
830 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200831 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
835 return ret;
836 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200839 }
840
841 /*
842 * Add message length
843 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 high = (ctx->total[0] >> 61)
845 | (ctx->total[1] << 3);
846 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 sha512_put_uint64_be(high, ctx->buffer, 112);
849 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
852 return ret;
853 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200855 /*
856 * Output final state
857 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 sha512_put_uint64_be(ctx->state[0], output, 0);
859 sha512_put_uint64_be(ctx->state[1], output, 8);
860 sha512_put_uint64_be(ctx->state[2], output, 16);
861 sha512_put_uint64_be(ctx->state[3], output, 24);
862 sha512_put_uint64_be(ctx->state[4], output, 32);
863 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000864
David Horstmann2788f6b2022-10-06 18:45:09 +0100865 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200866#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100867 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200868#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 if (!truncated) {
870 sha512_put_uint64_be(ctx->state[6], output, 48);
871 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000872 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100873
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000875}
876
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200878
Paul Bakker5121ce52009-01-03 21:22:43 +0000879/*
880 * output = SHA-512( input buffer )
881 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100882int mbedtls_sha512(const unsigned char *input,
883 size_t ilen,
884 unsigned char *output,
885 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000886{
Janos Follath24eed8d2019-11-22 13:21:35 +0000887 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000889
Valerio Setti43363f52022-12-14 08:53:23 +0100890#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100892 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 }
Valerio Setti43363f52022-12-14 08:53:23 +0100894#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100896 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 }
Valerio Setti43363f52022-12-14 08:53:23 +0100898#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100900 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100902#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 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
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100911 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100915 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100917
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100918exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000922}
923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000925
926/*
927 * FIPS-180-2 test vectors
928 */
Valerio Setti43363f52022-12-14 08:53:23 +0100929static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000930{
931 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 {
933 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
934 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 { "" }
936};
937
Valerio Setti43363f52022-12-14 08:53:23 +0100938static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000939{
940 3, 112, 1000
941};
942
Valerio Setti43363f52022-12-14 08:53:23 +0100943typedef const unsigned char (sha_test_sum_t)[64];
944
945/*
946 * SHA-384 test vectors
947 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200948#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100949static sha_test_sum_t sha384_test_sum[] =
950{
Paul Bakker5121ce52009-01-03 21:22:43 +0000951 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
952 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
953 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
954 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
955 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
956 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
957 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
958 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
959 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
960 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
961 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
962 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
963 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
964 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
965 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
966 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
967 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100968 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
969};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200970#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000971
Valerio Setti43363f52022-12-14 08:53:23 +0100972/*
973 * SHA-512 test vectors
974 */
975#if defined(MBEDTLS_SHA512_C)
976static sha_test_sum_t sha512_test_sum[] =
977{
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
979 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
980 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
981 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
982 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
983 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
984 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
985 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
986 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
987 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
988 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
989 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
990 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
991 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
992 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
993 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
994 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
995 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
996 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
997 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
998 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
999 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1000 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1001 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1002};
Valerio Setti43363f52022-12-14 08:53:23 +01001003#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +02001006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001008{
Valerio Setti43363f52022-12-14 08:53:23 +01001009 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001010 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001011 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001013
Valerio Setti43363f52022-12-14 08:53:23 +01001014#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001016#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001018#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001020#endif
1021
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1023 if (NULL == buf) {
1024 if (verbose != 0) {
1025 mbedtls_printf("Buffer allocation failed\n");
1026 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001029 }
1030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001032
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 for (i = 0; i < 3; i++) {
1034 if (verbose != 0) {
1035 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1036 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001039 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001041
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 if (i == 2) {
1043 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 for (int j = 0; j < 1000; j++) {
1046 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1047 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001048 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 }
1050 }
1051 } else {
1052 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1053 sha_test_buflen[i]);
1054 if (ret != 0) {
1055 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001056 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001057 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001058
1059 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1060 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001061 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001062
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001064 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001065 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001066 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001067
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 if (verbose != 0) {
1069 mbedtls_printf("passed\n");
1070 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001071 }
1072
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 if (verbose != 0) {
1074 mbedtls_printf("\n");
1075 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001076
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001077 goto exit;
1078
1079fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 if (verbose != 0) {
1081 mbedtls_printf("failed\n");
1082 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001083
Paul Bakker5b4af392014-06-26 12:09:34 +02001084exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 mbedtls_sha512_free(&ctx);
1086 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001087
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001089}
1090
Valerio Setti898e7a32022-12-14 08:55:53 +01001091#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001092int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001093{
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001095}
Valerio Setti898e7a32022-12-14 08:55:53 +01001096#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001097
Valerio Setti898e7a32022-12-14 08:55:53 +01001098#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001099int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001100{
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001102}
Valerio Setti898e7a32022-12-14 08:55:53 +01001103#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001104
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001105#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001106
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001108
Valerio Setti43363f52022-12-14 08:53:23 +01001109#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */