blob: 6dcea8da5d5c55b3110e403030756c2e65db4d1f [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
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
9 *
10 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
11 */
12
Jerry Yua135dee2023-02-16 16:56:22 +080013#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
Jerry Yu6f86c192023-03-13 11:03:40 +080014 defined(__clang__) && __clang_major__ >= 7
Jerry Yua135dee2023-02-16 16:56:22 +080015/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
16 *
Jerry Yufc2e1282023-02-27 11:16:56 +080017 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
18 * these are normally only enabled by the -march option on the command line.
19 * By defining the macros ourselves we gain access to those declarations without
20 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080021 *
Dave Rodgmana0f10da2023-09-05 11:43:17 +010022 * `arm_neon.h` is included by common.h, so we put these defines
Jerry Yufc2e1282023-02-27 11:16:56 +080023 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080024 */
25#define __ARM_FEATURE_SHA512 1
Dave Rodgmandb6ab242023-03-14 16:03:57 +000026#define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG
Jerry Yu490bf082023-03-06 15:21:44 +080027#endif
Jerry Yua135dee2023-02-16 16:56:22 +080028
Gilles Peskinedb09ef62020-06-03 01:43:33 +020029#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000030
Valerio Setti43363f52022-12-14 08:53:23 +010031#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000037#if defined(_MSC_VER) || defined(__WATCOMC__)
38 #define UL64(x) x##ui64
39#else
40 #define UL64(x) x##ULL
41#endif
42
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <string.h>
44
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000047#if defined(__aarch64__)
48# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010049 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080050/* *INDENT-OFF* */
Dave Rodgmana0f10da2023-09-05 11:43:17 +010051# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
Jerry Yu6b00f5a2023-05-04 16:30:21 +080052# error "Target does not support NEON instructions"
53# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080054/*
55 * Best performance comes from most recent compilers, with intrinsics and -O3.
56 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
57 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
58 *
59 * GCC < 8 won't work at all (lacks the sha512 instructions)
60 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
61 *
62 * Clang < 7 won't work at all (lacks the sha512 instructions)
63 * Clang 7-12 don't have intrinsics (but we work around that with inline
64 * assembler) or __ARM_FEATURE_SHA512
65 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
66 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
67 */
Dave Rodgmandb6ab242023-03-14 16:03:57 +000068# if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080069 /* Test Clang first, as it defines __GNUC__ */
Jerry Yu22a4d3e2023-04-28 17:43:40 +080070# if defined(__ARMCOMPILER_VERSION)
71# if __ARMCOMPILER_VERSION < 6090000
Jerry Yu8e96e782023-05-04 16:37:30 +080072# error "A more recent armclang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yub1d06bb2023-05-05 14:05:07 +080073# elif __ARMCOMPILER_VERSION == 6090000
74# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
75# else
Jerry Yu22a4d3e2023-04-28 17:43:40 +080076# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
77# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yub1d06bb2023-05-05 14:05:07 +080078# endif
Jerry Yu22a4d3e2023-04-28 17:43:40 +080079# elif defined(__clang__)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080080# if __clang_major__ < 7
81# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080082# else
Jerry Yu64e5d4a2023-02-15 11:46:57 +080083# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
84# define MBEDTLS_POP_TARGET_PRAGMA
85# endif
86# elif defined(__GNUC__)
87# if __GNUC__ < 8
88# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
89# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080090# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080091# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +080092# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080093# endif
94# else
95# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
96# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080097# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080098/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000099# endif
100# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
101# if defined(__unix__)
102# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100103/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000104# include <sys/auxv.h>
Dave Rodgmandae21d32024-01-30 15:31:42 +0000105# if !defined(HWCAP_SHA512)
106/* The same header that declares getauxval() should provide the HWCAP_xxx
107 * constants to analyze its return value. However, the libc may be too
108 * old to have the constant that we need. So if it's missing, assume that
109 * the value is the same one used by the Linux kernel ABI.
110 */
111# define HWCAP_SHA512 (1 << 21)
112# endif
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000113# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100114/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000115# include <signal.h>
116# endif
117# endif
Dave Rodgman0a487172023-09-15 11:52:06 +0100118#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000119# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
120# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
121#endif
122
123#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
124/*
125 * Capability detection code comes early, so we can disable
126 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
127 */
128#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100129static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000130{
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000132}
133#elif defined(__APPLE__)
134#include <sys/types.h>
135#include <sys/sysctl.h>
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000138{
139 int value = 0;
140 size_t value_len = sizeof(value);
141
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
143 NULL, 0);
144 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000145}
Dave Rodgman0a487172023-09-15 11:52:06 +0100146#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000147/*
148 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
149 * available to pass to IsProcessorFeaturePresent() to check for
150 * SHA-512 support. So we fall back to the C code only.
151 */
152#if defined(_MSC_VER)
153#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
154#else
155#warning "No mechanism to detect A64_CRYPTO found, using C code only"
156#endif
157#elif defined(__unix__) && defined(SIG_SETMASK)
158/* Detection with SIGILL, setjmp() and longjmp() */
159#include <signal.h>
160#include <setjmp.h>
161
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000162static jmp_buf return_from_sigill;
163
164/*
165 * A64 SHA512 support detection via SIGILL
166 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100167static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000168{
169 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000171}
172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000174{
175 struct sigaction old_action, new_action;
176
177 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 if (sigprocmask(0, NULL, &old_mask)) {
179 return 0;
180 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000183 new_action.sa_flags = 0;
184 new_action.sa_handler = sigill_handler;
185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000187
188 static int ret = 0;
189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000191 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000193 ret = 1;
194 }
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 sigaction(SIGILL, &old_action, NULL);
197 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000200}
201#else
202#warning "No mechanism to detect A64_CRYPTO found, using C code only"
203#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
204#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
205
206#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
207
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200208#if !defined(MBEDTLS_SHA512_ALT)
209
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000210#define SHA512_BLOCK_SIZE 128
211
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200212#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100213static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200214{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100215 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200216}
217#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100218#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200219#endif /* MBEDTLS_SHA512_SMALLER */
220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200222{
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200224}
225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200227{
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200229 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200233}
234
Gilles Peskine449bd832023-01-11 14:50:10 +0100235void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
236 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200237{
238 *dst = *src;
239}
240
Paul Bakker5121ce52009-01-03 21:22:43 +0000241/*
242 * SHA-512 context setup
243 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100244int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000245{
Valerio Setti43363f52022-12-14 08:53:23 +0100246#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100248 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 }
Valerio Setti43363f52022-12-14 08:53:23 +0100250#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100252 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 }
Valerio Setti43363f52022-12-14 08:53:23 +0100254#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100256 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100258#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000259
Paul Bakker5121ce52009-01-03 21:22:43 +0000260 ctx->total[0] = 0;
261 ctx->total[1] = 0;
262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100264#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000265 ctx->state[0] = UL64(0x6A09E667F3BCC908);
266 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
267 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
268 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
269 ctx->state[4] = UL64(0x510E527FADE682D1);
270 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
271 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
272 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100273#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100275#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000276 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
277 ctx->state[1] = UL64(0x629A292A367CD507);
278 ctx->state[2] = UL64(0x9159015A3070DD17);
279 ctx->state[3] = UL64(0x152FECD8F70E5939);
280 ctx->state[4] = UL64(0x67332667FFC00B31);
281 ctx->state[5] = UL64(0x8EB44A8768581511);
282 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
283 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200284#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 }
286
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200287#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200289#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000292}
293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200295
296/*
297 * Round constants
298 */
299static const uint64_t K[80] =
300{
301 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
302 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
303 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
304 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
305 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
306 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
307 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
308 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
309 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
310 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
311 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
312 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
313 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
314 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
315 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
316 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
317 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
318 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
319 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
320 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
321 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
322 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
323 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
324 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
325 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
326 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
327 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
328 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
329 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
330 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
331 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
332 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
333 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
334 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
335 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
336 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
337 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
338 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
339 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
340 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
341};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000342#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200343
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000344#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
345 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
346
347#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
348# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
349# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
350#endif
351
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000352/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
353 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
354 */
355
356#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 (__clang_major__ < 13 || \
358 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000359static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
360{
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
362 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000363}
364static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
365{
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
367 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000368}
369static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
370{
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
372 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000373}
374static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
375{
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
377 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000378}
379#endif /* __clang__ etc */
380
381static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000383{
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
385 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
386 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
387 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000388
389 size_t processed = 0;
390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 for (;
392 len >= SHA512_BLOCK_SIZE;
393 processed += SHA512_BLOCK_SIZE,
394 msg += SHA512_BLOCK_SIZE,
395 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000396 uint64x2_t initial_sum, sum, intermed;
397
398 uint64x2_t ab_orig = ab;
399 uint64x2_t cd_orig = cd;
400 uint64x2_t ef_orig = ef;
401 uint64x2_t gh_orig = gh;
402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
404 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
405 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
406 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
407 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
408 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
409 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
410 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000411
412#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
414 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
415 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
416 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
417 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
418 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
419 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
420 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000421#endif
422
423 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
425 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
426 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
427 gh = vsha512h2q_u64(intermed, cd, ab);
428 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000429
430 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
432 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
433 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
434 ef = vsha512h2q_u64(intermed, ab, gh);
435 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000436
437 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
439 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
440 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
441 cd = vsha512h2q_u64(intermed, gh, ef);
442 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000443
444 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
446 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
447 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
448 ab = vsha512h2q_u64(intermed, ef, cd);
449 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000450
451 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
453 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
454 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
455 gh = vsha512h2q_u64(intermed, cd, ab);
456 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000457
458 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
460 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
461 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
462 ef = vsha512h2q_u64(intermed, ab, gh);
463 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000464
465 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
467 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
468 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
469 cd = vsha512h2q_u64(intermed, gh, ef);
470 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000471
472 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
474 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
475 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
476 ab = vsha512h2q_u64(intermed, ef, cd);
477 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000480 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
482 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
483 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
484 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
485 gh = vsha512h2q_u64(intermed, cd, ab);
486 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000487
488 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
490 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
491 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
492 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
493 ef = vsha512h2q_u64(intermed, ab, gh);
494 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000495
496 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
498 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
499 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
500 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
501 cd = vsha512h2q_u64(intermed, gh, ef);
502 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000503
504 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
506 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
507 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
508 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
509 ab = vsha512h2q_u64(intermed, ef, cd);
510 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000511
512 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
514 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
515 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
516 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
517 gh = vsha512h2q_u64(intermed, cd, ab);
518 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000519
520 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
522 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
523 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
524 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
525 ef = vsha512h2q_u64(intermed, ab, gh);
526 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000527
528 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
530 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
531 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
532 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
533 cd = vsha512h2q_u64(intermed, gh, ef);
534 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000535
536 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
538 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
539 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
540 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
541 ab = vsha512h2q_u64(intermed, ef, cd);
542 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000543 }
544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 ab = vaddq_u64(ab, ab_orig);
546 cd = vaddq_u64(cd, cd_orig);
547 ef = vaddq_u64(ef, ef_orig);
548 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000549 }
550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 vst1q_u64(&ctx->state[0], ab);
552 vst1q_u64(&ctx->state[2], cd);
553 vst1q_u64(&ctx->state[4], ef);
554 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000557}
558
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100559#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
560/*
561 * This function is for internal use only if we are building both C and A64
562 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
563 */
564static
565#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100566int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
567 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000568{
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
570 SHA512_BLOCK_SIZE) ==
571 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000572}
573
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100574#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
575
Jerry Yu92fc5382023-02-16 11:17:11 +0800576#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800577#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800578#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800579#elif defined(__GNUC__)
580#pragma GCC pop_options
581#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800582#undef MBEDTLS_POP_TARGET_PRAGMA
583#endif
584
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000585
586#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
587#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
588#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
589#endif
590
591
592#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
593
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100594#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
595/*
596 * This function is for internal use only if we are building both C and A64
597 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
598 */
599static
600#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100601int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
602 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000603{
604 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200606 uint64_t temp1, temp2, W[80];
607 uint64_t A[8];
608 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610#define SHR(x, n) ((x) >> (n))
611#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100614#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
617#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
620#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Gilles Peskine449bd832023-01-11 14:50:10 +0100622#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200623 do \
624 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
626 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200627 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200631 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200633
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200634#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 for (i = 0; i < 80; i++) {
636 if (i < 16) {
637 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
638 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200639 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200641 }
642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
644 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200645
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200646 local.temp1 = local.A[7]; local.A[7] = local.A[6];
647 local.A[6] = local.A[5]; local.A[5] = local.A[4];
648 local.A[4] = local.A[3]; local.A[3] = local.A[2];
649 local.A[2] = local.A[1]; local.A[1] = local.A[0];
650 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200651 }
652#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 for (i = 0; i < 16; i++) {
654 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000655 }
656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200658 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 }
661
Paul Bakker5121ce52009-01-03 21:22:43 +0000662 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 do {
664 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
665 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
666 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
667 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
668 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
669 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
670 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
671 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
672 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
673 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
674 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
675 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
676 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
677 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
678 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
679 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
680 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200681#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200684 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100686
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200687 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000691}
Jaeden Amero041039f2018-02-19 15:28:08 +0000692
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000693#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
694
695
696#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
697
698static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000700{
701 size_t processed = 0;
702
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 while (len >= SHA512_BLOCK_SIZE) {
704 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
705 return 0;
706 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000707
708 data += SHA512_BLOCK_SIZE;
709 len -= SHA512_BLOCK_SIZE;
710
711 processed += SHA512_BLOCK_SIZE;
712 }
713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000715}
716
717#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
718
719
720#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000723{
724 static int done = 0;
725 static int supported = 0;
726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000728 supported = mbedtls_a64_crypto_sha512_determine_support();
729 done = 1;
730 }
731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000733}
734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
736 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000737{
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (mbedtls_a64_crypto_sha512_has_support()) {
739 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
740 } else {
741 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
742 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000743}
744
Gilles Peskine449bd832023-01-11 14:50:10 +0100745int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
746 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000747{
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 if (mbedtls_a64_crypto_sha512_has_support()) {
749 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
750 } else {
751 return mbedtls_internal_sha512_process_c(ctx, data);
752 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000753}
754
755#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000756
757/*
758 * SHA-512 process buffer
759 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100760int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
761 const unsigned char *input,
762 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000763{
Janos Follath24eed8d2019-11-22 13:21:35 +0000764 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000765 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000766 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 if (ilen == 0) {
769 return 0;
770 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Paul Bakkerb8213a12011-07-11 08:16:18 +0000772 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000773 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000774
Paul Bakker5c2364c2012-10-01 14:41:15 +0000775 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000776
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000778 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 if (left && ilen >= fill) {
782 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100783
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
785 return ret;
786 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100787
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 input += fill;
789 ilen -= fill;
790 left = 0;
791 }
792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000794 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 mbedtls_internal_sha512_process_many(ctx, input, ilen);
796 if (processed < SHA512_BLOCK_SIZE) {
797 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
798 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100799
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000800 input += processed;
801 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000802 }
803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 if (ilen > 0) {
805 memcpy((void *) (ctx->buffer + left), input, ilen);
806 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100807
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000809}
810
Paul Bakker5121ce52009-01-03 21:22:43 +0000811/*
812 * SHA-512 final digest
813 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100814int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
815 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000816{
Janos Follath24eed8d2019-11-22 13:21:35 +0000817 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200818 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000819 uint64_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100820 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000821
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200822 /*
823 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
824 */
825 used = ctx->total[0] & 0x7F;
826
827 ctx->buffer[used++] = 0x80;
828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200830 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 memset(ctx->buffer + used, 0, 112 - used);
832 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200833 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100837 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200841 }
842
843 /*
844 * Add message length
845 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 high = (ctx->total[0] >> 61)
847 | (ctx->total[1] << 3);
848 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 sha512_put_uint64_be(high, ctx->buffer, 112);
851 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100854 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000856
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200857 /*
858 * Output final state
859 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 sha512_put_uint64_be(ctx->state[0], output, 0);
861 sha512_put_uint64_be(ctx->state[1], output, 8);
862 sha512_put_uint64_be(ctx->state[2], output, 16);
863 sha512_put_uint64_be(ctx->state[3], output, 24);
864 sha512_put_uint64_be(ctx->state[4], output, 32);
865 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000866
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200867#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100868 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200869#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 if (!truncated) {
871 sha512_put_uint64_be(ctx->state[6], output, 48);
872 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000873 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100874
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100875 ret = 0;
876
877exit:
878 mbedtls_sha512_free(ctx);
879 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000880}
881
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200883
Paul Bakker5121ce52009-01-03 21:22:43 +0000884/*
885 * output = SHA-512( input buffer )
886 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100887int mbedtls_sha512(const unsigned char *input,
888 size_t ilen,
889 unsigned char *output,
890 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000891{
Janos Follath24eed8d2019-11-22 13:21:35 +0000892 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000894
Valerio Setti43363f52022-12-14 08:53:23 +0100895#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100897 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 }
Valerio Setti43363f52022-12-14 08:53:23 +0100899#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100901 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 }
Valerio Setti43363f52022-12-14 08:53:23 +0100903#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100905 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100907#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100912 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100914
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100916 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100920 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100922
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100923exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100925
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000927}
928
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000930
931/*
932 * FIPS-180-2 test vectors
933 */
Valerio Setti43363f52022-12-14 08:53:23 +0100934static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000935{
936 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 {
938 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
939 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000940 { "" }
941};
942
Valerio Setti43363f52022-12-14 08:53:23 +0100943static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000944{
945 3, 112, 1000
946};
947
Valerio Setti43363f52022-12-14 08:53:23 +0100948typedef const unsigned char (sha_test_sum_t)[64];
949
950/*
951 * SHA-384 test vectors
952 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200953#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100954static sha_test_sum_t sha384_test_sum[] =
955{
Paul Bakker5121ce52009-01-03 21:22:43 +0000956 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
957 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
958 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
959 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
960 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
961 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
962 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
963 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
964 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
965 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
966 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
967 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
968 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
969 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
970 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
971 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
972 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100973 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
974};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200975#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000976
Valerio Setti43363f52022-12-14 08:53:23 +0100977/*
978 * SHA-512 test vectors
979 */
980#if defined(MBEDTLS_SHA512_C)
981static sha_test_sum_t sha512_test_sum[] =
982{
Paul Bakker5121ce52009-01-03 21:22:43 +0000983 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
984 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
985 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
986 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
987 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
988 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
989 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
990 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
991 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
992 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
993 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
994 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
995 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
996 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
997 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
998 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
999 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
1000 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1001 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1002 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1003 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1004 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1005 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1006 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1007};
Valerio Setti43363f52022-12-14 08:53:23 +01001008#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001011{
Valerio Setti43363f52022-12-14 08:53:23 +01001012 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001013 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001014 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001015 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001016
Valerio Setti43363f52022-12-14 08:53:23 +01001017#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001019#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001021#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001023#endif
1024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1026 if (NULL == buf) {
1027 if (verbose != 0) {
1028 mbedtls_printf("Buffer allocation failed\n");
1029 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001032 }
1033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001035
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 for (i = 0; i < 3; i++) {
1037 if (verbose != 0) {
1038 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1039 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001042 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 if (i == 2) {
1046 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 for (int j = 0; j < 1000; j++) {
1049 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1050 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001051 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 }
1053 }
1054 } else {
1055 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1056 sha_test_buflen[i]);
1057 if (ret != 0) {
1058 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001059 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001061
1062 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1063 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001064 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001067 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001068 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001069 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001070
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 if (verbose != 0) {
1072 mbedtls_printf("passed\n");
1073 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001074 }
1075
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 if (verbose != 0) {
1077 mbedtls_printf("\n");
1078 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001079
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001080 goto exit;
1081
1082fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 if (verbose != 0) {
1084 mbedtls_printf("failed\n");
1085 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001086
Paul Bakker5b4af392014-06-26 12:09:34 +02001087exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 mbedtls_sha512_free(&ctx);
1089 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001090
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001092}
1093
Valerio Setti898e7a32022-12-14 08:55:53 +01001094#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001095int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001096{
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001098}
Valerio Setti898e7a32022-12-14 08:55:53 +01001099#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001100
Valerio Setti898e7a32022-12-14 08:55:53 +01001101#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001102int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001103{
Gilles Peskine449bd832023-01-11 14:50:10 +01001104 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001105}
Valerio Setti898e7a32022-12-14 08:55:53 +01001106#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001107
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001108#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001110#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001111
Valerio Setti43363f52022-12-14 08:53:23 +01001112#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */