blob: df8c5a9c1dd76497e5e1b35597fe1b47ca239327 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Valerio Setti43363f52022-12-14 08:53:23 +010027#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000033#if defined(_MSC_VER) || defined(__WATCOMC__)
34 #define UL64(x) x##ui64
35#else
36 #define UL64(x) x##ULL
37#endif
38
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010042
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000043#if defined(__aarch64__)
44# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010045 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080046/* *INDENT-OFF* */
47/*
48 * Best performance comes from most recent compilers, with intrinsics and -O3.
49 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
50 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
51 *
52 * GCC < 8 won't work at all (lacks the sha512 instructions)
53 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
54 *
55 * Clang < 7 won't work at all (lacks the sha512 instructions)
56 * Clang 7-12 don't have intrinsics (but we work around that with inline
57 * assembler) or __ARM_FEATURE_SHA512
58 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
59 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
60 */
Jerry Yu64e5d4a2023-02-15 11:46:57 +080061# if !defined(__ARM_FEATURE_SHA512)
62 /* Test Clang first, as it defines __GNUC__ */
63# if defined(__clang__)
64# if __clang_major__ < 7
65# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
66# elif __clang_major__ < 13 || \
67 (__clang_major__ == 13 && __clang_minor__ == 0 && \
68 __clang_patchlevel__ == 0)
69 /* We implement the intrinsics with inline assembler, so don't error */
70# else
71# if __clang_major__ < 18
72 /* TODO: Re-consider above after https://reviews.llvm.org/D131064
73 * merged.
74 *
75 * The intrinsic declaration are guarded with ACLE predefined macros
76 * in clang, and those macros are only enabled with command line.
77 * Define the macros can enable those declaration and avoid compile
78 * error on it.
79 */
80# define __ARM_FEATURE_SHA512 1
81# endif
82# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
83# define MBEDTLS_POP_TARGET_PRAGMA
84# endif
85# elif defined(__GNUC__)
86# if __GNUC__ < 8
87# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
88# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080089# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080090# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +080091# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080092# endif
93# else
94# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
95# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080096# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080097/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000098# include <arm_neon.h>
99# 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>
105# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100106/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000107# include <signal.h>
108# endif
109# endif
110#elif defined(_M_ARM64)
111# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100112 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000113# include <arm64_neon.h>
114# endif
115#else
116# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
117# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
118#endif
119
120#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
121/*
122 * Capability detection code comes early, so we can disable
123 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
124 */
125#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100126static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000127{
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000129}
130#elif defined(__APPLE__)
131#include <sys/types.h>
132#include <sys/sysctl.h>
133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000135{
136 int value = 0;
137 size_t value_len = sizeof(value);
138
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
140 NULL, 0);
141 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000142}
143#elif defined(_M_ARM64)
144/*
145 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
146 * available to pass to IsProcessorFeaturePresent() to check for
147 * SHA-512 support. So we fall back to the C code only.
148 */
149#if defined(_MSC_VER)
150#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
151#else
152#warning "No mechanism to detect A64_CRYPTO found, using C code only"
153#endif
154#elif defined(__unix__) && defined(SIG_SETMASK)
155/* Detection with SIGILL, setjmp() and longjmp() */
156#include <signal.h>
157#include <setjmp.h>
158
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000159static jmp_buf return_from_sigill;
160
161/*
162 * A64 SHA512 support detection via SIGILL
163 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100164static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000165{
166 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000168}
169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000171{
172 struct sigaction old_action, new_action;
173
174 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 if (sigprocmask(0, NULL, &old_mask)) {
176 return 0;
177 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000180 new_action.sa_flags = 0;
181 new_action.sa_handler = sigill_handler;
182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000184
185 static int ret = 0;
186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000188 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000190 ret = 1;
191 }
192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 sigaction(SIGILL, &old_action, NULL);
194 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000197}
198#else
199#warning "No mechanism to detect A64_CRYPTO found, using C code only"
200#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
201#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
202
203#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
204
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200205#if !defined(MBEDTLS_SHA512_ALT)
206
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000207#define SHA512_BLOCK_SIZE 128
208
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200209#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100210static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200211{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100212 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200213}
214#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100215#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200216#endif /* MBEDTLS_SHA512_SMALLER */
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200219{
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200221}
222
Gilles Peskine449bd832023-01-11 14:50:10 +0100223void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200224{
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200226 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200230}
231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
233 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200234{
235 *dst = *src;
236}
237
Paul Bakker5121ce52009-01-03 21:22:43 +0000238/*
239 * SHA-512 context setup
240 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100241int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000242{
Valerio Setti43363f52022-12-14 08:53:23 +0100243#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100245 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 }
Valerio Setti43363f52022-12-14 08:53:23 +0100247#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100249 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 }
Valerio Setti43363f52022-12-14 08:53:23 +0100251#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100253 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100255#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000256
Paul Bakker5121ce52009-01-03 21:22:43 +0000257 ctx->total[0] = 0;
258 ctx->total[1] = 0;
259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100261#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000262 ctx->state[0] = UL64(0x6A09E667F3BCC908);
263 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
264 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
265 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
266 ctx->state[4] = UL64(0x510E527FADE682D1);
267 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
268 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
269 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100270#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100272#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
274 ctx->state[1] = UL64(0x629A292A367CD507);
275 ctx->state[2] = UL64(0x9159015A3070DD17);
276 ctx->state[3] = UL64(0x152FECD8F70E5939);
277 ctx->state[4] = UL64(0x67332667FFC00B31);
278 ctx->state[5] = UL64(0x8EB44A8768581511);
279 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
280 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200281#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000282 }
283
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200284#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200286#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000289}
290
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200292
293/*
294 * Round constants
295 */
296static const uint64_t K[80] =
297{
298 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
299 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
300 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
301 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
302 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
303 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
304 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
305 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
306 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
307 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
308 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
309 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
310 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
311 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
312 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
313 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
314 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
315 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
316 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
317 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
318 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
319 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
320 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
321 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
322 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
323 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
324 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
325 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
326 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
327 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
328 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
329 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
330 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
331 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
332 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
333 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
334 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
335 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
336 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
337 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
338};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000339#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200340
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000341#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
342 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
343
344#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
345# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
346# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
347#endif
348
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000349/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
350 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
351 */
352
353#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 (__clang_major__ < 13 || \
355 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000356static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
357{
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
359 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000360}
361static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
362{
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
364 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000365}
366static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
367{
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
369 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000370}
371static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
372{
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
374 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000375}
376#endif /* __clang__ etc */
377
378static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000380{
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
382 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
383 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
384 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000385
386 size_t processed = 0;
387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 for (;
389 len >= SHA512_BLOCK_SIZE;
390 processed += SHA512_BLOCK_SIZE,
391 msg += SHA512_BLOCK_SIZE,
392 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000393 uint64x2_t initial_sum, sum, intermed;
394
395 uint64x2_t ab_orig = ab;
396 uint64x2_t cd_orig = cd;
397 uint64x2_t ef_orig = ef;
398 uint64x2_t gh_orig = gh;
399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
401 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
402 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
403 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
404 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
405 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
406 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
407 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000408
409#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
411 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
412 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
413 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
414 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
415 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
416 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
417 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000418#endif
419
420 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
422 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
423 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
424 gh = vsha512h2q_u64(intermed, cd, ab);
425 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000426
427 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
429 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
430 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
431 ef = vsha512h2q_u64(intermed, ab, gh);
432 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000433
434 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
436 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
437 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
438 cd = vsha512h2q_u64(intermed, gh, ef);
439 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000440
441 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
443 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
444 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
445 ab = vsha512h2q_u64(intermed, ef, cd);
446 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000447
448 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
450 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
451 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
452 gh = vsha512h2q_u64(intermed, cd, ab);
453 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000454
455 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
457 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
458 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
459 ef = vsha512h2q_u64(intermed, ab, gh);
460 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000461
462 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
464 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
465 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
466 cd = vsha512h2q_u64(intermed, gh, ef);
467 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000468
469 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
471 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
472 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
473 ab = vsha512h2q_u64(intermed, ef, cd);
474 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000477 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
479 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
480 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
481 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
482 gh = vsha512h2q_u64(intermed, cd, ab);
483 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000484
485 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
487 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
488 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
489 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
490 ef = vsha512h2q_u64(intermed, ab, gh);
491 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000492
493 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
495 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
496 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
497 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
498 cd = vsha512h2q_u64(intermed, gh, ef);
499 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000500
501 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
503 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
504 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
505 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
506 ab = vsha512h2q_u64(intermed, ef, cd);
507 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000508
509 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
511 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
512 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
513 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
514 gh = vsha512h2q_u64(intermed, cd, ab);
515 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000516
517 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
519 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
520 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
521 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
522 ef = vsha512h2q_u64(intermed, ab, gh);
523 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000524
525 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
527 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
528 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
529 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
530 cd = vsha512h2q_u64(intermed, gh, ef);
531 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000532
533 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
535 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
536 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
537 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
538 ab = vsha512h2q_u64(intermed, ef, cd);
539 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000540 }
541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 ab = vaddq_u64(ab, ab_orig);
543 cd = vaddq_u64(cd, cd_orig);
544 ef = vaddq_u64(ef, ef_orig);
545 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000546 }
547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 vst1q_u64(&ctx->state[0], ab);
549 vst1q_u64(&ctx->state[2], cd);
550 vst1q_u64(&ctx->state[4], ef);
551 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000554}
555
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100556#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
557/*
558 * This function is for internal use only if we are building both C and A64
559 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
560 */
561static
562#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100563int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
564 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000565{
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
567 SHA512_BLOCK_SIZE) ==
568 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000569}
570
Jerry Yu92fc5382023-02-16 11:17:11 +0800571#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800572#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800573#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800574#elif defined(__GNUC__)
575#pragma GCC pop_options
576#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800577#undef MBEDTLS_POP_TARGET_PRAGMA
578#endif
579
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000580#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
581
582
583#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
584#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
585#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
586#endif
587
588
589#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
590
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100591#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
592/*
593 * This function is for internal use only if we are building both C and A64
594 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
595 */
596static
597#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100598int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
599 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000600{
601 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200603 uint64_t temp1, temp2, W[80];
604 uint64_t A[8];
605 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607#define SHR(x, n) ((x) >> (n))
608#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
610#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100611#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
614#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
617#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200620 do \
621 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
623 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200624 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200628 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200630
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200631#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 for (i = 0; i < 80; i++) {
633 if (i < 16) {
634 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
635 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200636 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200638 }
639
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
641 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200642
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200643 local.temp1 = local.A[7]; local.A[7] = local.A[6];
644 local.A[6] = local.A[5]; local.A[5] = local.A[4];
645 local.A[4] = local.A[3]; local.A[3] = local.A[2];
646 local.A[2] = local.A[1]; local.A[1] = local.A[0];
647 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200648 }
649#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 for (i = 0; i < 16; i++) {
651 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 }
653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200655 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 }
658
Paul Bakker5121ce52009-01-03 21:22:43 +0000659 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 do {
661 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
662 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
663 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
664 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
665 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
666 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
667 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
668 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
669 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
670 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
671 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
672 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
673 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
674 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
675 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
676 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
677 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200678#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200681 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100683
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200684 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100686
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000688}
Jaeden Amero041039f2018-02-19 15:28:08 +0000689
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000690#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
691
692
693#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
694
695static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000697{
698 size_t processed = 0;
699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 while (len >= SHA512_BLOCK_SIZE) {
701 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
702 return 0;
703 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000704
705 data += SHA512_BLOCK_SIZE;
706 len -= SHA512_BLOCK_SIZE;
707
708 processed += SHA512_BLOCK_SIZE;
709 }
710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000712}
713
714#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
715
716
717#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000720{
721 static int done = 0;
722 static int supported = 0;
723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000725 supported = mbedtls_a64_crypto_sha512_determine_support();
726 done = 1;
727 }
728
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000730}
731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
733 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000734{
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 if (mbedtls_a64_crypto_sha512_has_support()) {
736 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
737 } else {
738 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
739 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000740}
741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
743 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000744{
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 if (mbedtls_a64_crypto_sha512_has_support()) {
746 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
747 } else {
748 return mbedtls_internal_sha512_process_c(ctx, data);
749 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000750}
751
752#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
754/*
755 * SHA-512 process buffer
756 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100757int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
758 const unsigned char *input,
759 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000760{
Janos Follath24eed8d2019-11-22 13:21:35 +0000761 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000762 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000763 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if (ilen == 0) {
766 return 0;
767 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
Paul Bakkerb8213a12011-07-11 08:16:18 +0000769 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000770 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Paul Bakker5c2364c2012-10-01 14:41:15 +0000772 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000775 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000777
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 if (left && ilen >= fill) {
779 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
782 return ret;
783 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100784
Paul Bakker5121ce52009-01-03 21:22:43 +0000785 input += fill;
786 ilen -= fill;
787 left = 0;
788 }
789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000791 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 mbedtls_internal_sha512_process_many(ctx, input, ilen);
793 if (processed < SHA512_BLOCK_SIZE) {
794 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
795 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100796
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000797 input += processed;
798 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000799 }
800
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 if (ilen > 0) {
802 memcpy((void *) (ctx->buffer + left), input, ilen);
803 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000806}
807
Paul Bakker5121ce52009-01-03 21:22:43 +0000808/*
809 * SHA-512 final digest
810 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100811int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
812 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000813{
Janos Follath24eed8d2019-11-22 13:21:35 +0000814 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200815 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000816 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000817
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200818 /*
819 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
820 */
821 used = ctx->total[0] & 0x7F;
822
823 ctx->buffer[used++] = 0x80;
824
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200826 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 memset(ctx->buffer + used, 0, 112 - used);
828 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200829 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
833 return ret;
834 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200837 }
838
839 /*
840 * Add message length
841 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 high = (ctx->total[0] >> 61)
843 | (ctx->total[1] << 3);
844 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 sha512_put_uint64_be(high, ctx->buffer, 112);
847 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000848
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
850 return ret;
851 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000852
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200853 /*
854 * Output final state
855 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 sha512_put_uint64_be(ctx->state[0], output, 0);
857 sha512_put_uint64_be(ctx->state[1], output, 8);
858 sha512_put_uint64_be(ctx->state[2], output, 16);
859 sha512_put_uint64_be(ctx->state[3], output, 24);
860 sha512_put_uint64_be(ctx->state[4], output, 32);
861 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
David Horstmann2788f6b2022-10-06 18:45:09 +0100863 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200864#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100865 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200866#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 if (!truncated) {
868 sha512_put_uint64_be(ctx->state[6], output, 48);
869 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000870 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000873}
874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200876
Paul Bakker5121ce52009-01-03 21:22:43 +0000877/*
878 * output = SHA-512( input buffer )
879 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100880int mbedtls_sha512(const unsigned char *input,
881 size_t ilen,
882 unsigned char *output,
883 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000884{
Janos Follath24eed8d2019-11-22 13:21:35 +0000885 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200886 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000887
Valerio Setti43363f52022-12-14 08:53:23 +0100888#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100890 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 }
Valerio Setti43363f52022-12-14 08:53:23 +0100892#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100894 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 }
Valerio Setti43363f52022-12-14 08:53:23 +0100896#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100898 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100900#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100905 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100909 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100913 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100915
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100916exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000920}
921
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
924/*
925 * FIPS-180-2 test vectors
926 */
Valerio Setti43363f52022-12-14 08:53:23 +0100927static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000928{
929 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 {
931 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
932 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 { "" }
934};
935
Valerio Setti43363f52022-12-14 08:53:23 +0100936static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000937{
938 3, 112, 1000
939};
940
Valerio Setti43363f52022-12-14 08:53:23 +0100941typedef const unsigned char (sha_test_sum_t)[64];
942
943/*
944 * SHA-384 test vectors
945 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200946#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100947static sha_test_sum_t sha384_test_sum[] =
948{
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
950 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
951 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
952 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
953 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
954 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
955 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
956 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
957 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
958 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
959 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
960 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
961 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
962 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
963 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
964 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
965 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100966 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
967};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200968#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000969
Valerio Setti43363f52022-12-14 08:53:23 +0100970/*
971 * SHA-512 test vectors
972 */
973#if defined(MBEDTLS_SHA512_C)
974static sha_test_sum_t sha512_test_sum[] =
975{
Paul Bakker5121ce52009-01-03 21:22:43 +0000976 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
977 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
978 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
979 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
980 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
981 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
982 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
983 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
984 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
985 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
986 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
987 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
988 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
989 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
990 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
991 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
992 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
993 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
994 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
995 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
996 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
997 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
998 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
999 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1000};
Valerio Setti43363f52022-12-14 08:53:23 +01001001#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +02001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001006{
Valerio Setti43363f52022-12-14 08:53:23 +01001007 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001008 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001009 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001011
Valerio Setti43363f52022-12-14 08:53:23 +01001012#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001014#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001016#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001018#endif
1019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1021 if (NULL == buf) {
1022 if (verbose != 0) {
1023 mbedtls_printf("Buffer allocation failed\n");
1024 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001025
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001027 }
1028
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 for (i = 0; i < 3; i++) {
1032 if (verbose != 0) {
1033 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1034 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001035
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001037 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 if (i == 2) {
1041 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 for (int j = 0; j < 1000; j++) {
1044 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1045 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001046 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 }
1048 }
1049 } else {
1050 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1051 sha_test_buflen[i]);
1052 if (ret != 0) {
1053 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001054 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001055 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001056
1057 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1058 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001059 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001060
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001062 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001063 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001064 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (verbose != 0) {
1067 mbedtls_printf("passed\n");
1068 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001069 }
1070
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 if (verbose != 0) {
1072 mbedtls_printf("\n");
1073 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001074
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001075 goto exit;
1076
1077fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 if (verbose != 0) {
1079 mbedtls_printf("failed\n");
1080 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001081
Paul Bakker5b4af392014-06-26 12:09:34 +02001082exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 mbedtls_sha512_free(&ctx);
1084 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001087}
1088
Valerio Setti898e7a32022-12-14 08:55:53 +01001089#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001090int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001091{
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001093}
Valerio Setti898e7a32022-12-14 08:55:53 +01001094#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001095
Valerio Setti898e7a32022-12-14 08:55:53 +01001096#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001097int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001098{
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001100}
Valerio Setti898e7a32022-12-14 08:55:53 +01001101#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001102
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001103#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001105#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001106
Valerio Setti43363f52022-12-14 08:53:23 +01001107#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */