blob: 26b46318d3798684da0115ec6ea6dd7cf2e48b94 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Jerry Yua135dee2023-02-16 16:56:22 +080025#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
26 defined(__clang__) && __clang_major__ < 18 && \
27 __clang_major__ >= 13 && __clang_minor__ > 0 && __clang_patchlevel__ > 0
28/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
29 *
30 * The intrinsic declaration are guarded with ACLE predefined macros in clang,
31 * and those macros are only enabled with command line. Define the macros can
32 * enable those declaration and avoid compile error on it.
33 */
34#define __ARM_FEATURE_SHA512 1
35#pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
36#define MBEDTLS_POP_TARGET_PRAGMA
37#endif /* __aarch64__ && __clang__ &&
Jerry Yuba4ec242023-02-21 15:59:13 +080038 !__ARM_FEATURE_SHA512 && __clang_major__ < 18 &&
39 __clang_major__ >= 13 && __clang_minor__ > 0 &&
40 __clang_patchlevel__ > 0 */
Jerry Yua135dee2023-02-16 16:56:22 +080041
Gilles Peskinedb09ef62020-06-03 01:43:33 +020042#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000043
Jerry Yua135dee2023-02-16 16:56:22 +080044#if defined(MBEDTLS_POP_TARGET_PRAGMA) && \
45 !(defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Jerry Yuba4ec242023-02-21 15:59:13 +080046 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY))
Jerry Yua135dee2023-02-16 16:56:22 +080047#if defined(__clang__)
48#pragma clang attribute pop
49#endif
50#undef MBEDTLS_POP_TARGET_PRAGMA
51#endif
52
Valerio Setti43363f52022-12-14 08:53:23 +010053#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000054
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050056#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000057#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000058
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000059#if defined(_MSC_VER) || defined(__WATCOMC__)
60 #define UL64(x) x##ui64
61#else
62 #define UL64(x) x##ULL
63#endif
64
Rich Evans00ab4702015-02-06 13:43:58 +000065#include <string.h>
66
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000069#if defined(__aarch64__)
70# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010071 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080072/* *INDENT-OFF* */
73/*
74 * Best performance comes from most recent compilers, with intrinsics and -O3.
75 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
76 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
77 *
78 * GCC < 8 won't work at all (lacks the sha512 instructions)
79 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
80 *
81 * Clang < 7 won't work at all (lacks the sha512 instructions)
82 * Clang 7-12 don't have intrinsics (but we work around that with inline
83 * assembler) or __ARM_FEATURE_SHA512
84 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
85 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
86 */
Jerry Yu64e5d4a2023-02-15 11:46:57 +080087# if !defined(__ARM_FEATURE_SHA512)
88 /* Test Clang first, as it defines __GNUC__ */
89# if defined(__clang__)
90# if __clang_major__ < 7
91# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
92# elif __clang_major__ < 13 || \
93 (__clang_major__ == 13 && __clang_minor__ == 0 && \
94 __clang_patchlevel__ == 0)
95 /* We implement the intrinsics with inline assembler, so don't error */
96# else
Jerry Yu64e5d4a2023-02-15 11:46:57 +080097# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
98# define MBEDTLS_POP_TARGET_PRAGMA
99# endif
100# elif defined(__GNUC__)
101# if __GNUC__ < 8
102# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
103# else
Jerry Yu2f2c0492023-02-16 14:24:46 +0800104# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800105# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +0800106# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800107# endif
108# else
109# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
110# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800111# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800112/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000113# include <arm_neon.h>
114# endif
115# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
116# if defined(__unix__)
117# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100118/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000119# include <sys/auxv.h>
120# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100121/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000122# include <signal.h>
123# endif
124# endif
125#elif defined(_M_ARM64)
126# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000128# include <arm64_neon.h>
129# endif
130#else
131# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
132# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
133#endif
134
135#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
136/*
137 * Capability detection code comes early, so we can disable
138 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
139 */
140#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100141static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000142{
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000144}
145#elif defined(__APPLE__)
146#include <sys/types.h>
147#include <sys/sysctl.h>
148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000150{
151 int value = 0;
152 size_t value_len = sizeof(value);
153
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
155 NULL, 0);
156 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000157}
158#elif defined(_M_ARM64)
159/*
160 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
161 * available to pass to IsProcessorFeaturePresent() to check for
162 * SHA-512 support. So we fall back to the C code only.
163 */
164#if defined(_MSC_VER)
165#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
166#else
167#warning "No mechanism to detect A64_CRYPTO found, using C code only"
168#endif
169#elif defined(__unix__) && defined(SIG_SETMASK)
170/* Detection with SIGILL, setjmp() and longjmp() */
171#include <signal.h>
172#include <setjmp.h>
173
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000174static jmp_buf return_from_sigill;
175
176/*
177 * A64 SHA512 support detection via SIGILL
178 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100179static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000180{
181 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000183}
184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000186{
187 struct sigaction old_action, new_action;
188
189 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 if (sigprocmask(0, NULL, &old_mask)) {
191 return 0;
192 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000195 new_action.sa_flags = 0;
196 new_action.sa_handler = sigill_handler;
197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000199
200 static int ret = 0;
201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000203 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000205 ret = 1;
206 }
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 sigaction(SIGILL, &old_action, NULL);
209 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000210
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000212}
213#else
214#warning "No mechanism to detect A64_CRYPTO found, using C code only"
215#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
216#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
217
218#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
219
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200220#if !defined(MBEDTLS_SHA512_ALT)
221
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000222#define SHA512_BLOCK_SIZE 128
223
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200224#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100225static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200226{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100227 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200228}
229#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100230#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200231#endif /* MBEDTLS_SHA512_SMALLER */
232
Gilles Peskine449bd832023-01-11 14:50:10 +0100233void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200234{
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200236}
237
Gilles Peskine449bd832023-01-11 14:50:10 +0100238void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200239{
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200241 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200245}
246
Gilles Peskine449bd832023-01-11 14:50:10 +0100247void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
248 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200249{
250 *dst = *src;
251}
252
Paul Bakker5121ce52009-01-03 21:22:43 +0000253/*
254 * SHA-512 context setup
255 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100256int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000257{
Valerio Setti43363f52022-12-14 08:53:23 +0100258#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100260 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 }
Valerio Setti43363f52022-12-14 08:53:23 +0100262#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100264 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 }
Valerio Setti43363f52022-12-14 08:53:23 +0100266#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100268 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100270#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000271
Paul Bakker5121ce52009-01-03 21:22:43 +0000272 ctx->total[0] = 0;
273 ctx->total[1] = 0;
274
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100276#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 ctx->state[0] = UL64(0x6A09E667F3BCC908);
278 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
279 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
280 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
281 ctx->state[4] = UL64(0x510E527FADE682D1);
282 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
283 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
284 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100285#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100287#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
289 ctx->state[1] = UL64(0x629A292A367CD507);
290 ctx->state[2] = UL64(0x9159015A3070DD17);
291 ctx->state[3] = UL64(0x152FECD8F70E5939);
292 ctx->state[4] = UL64(0x67332667FFC00B31);
293 ctx->state[5] = UL64(0x8EB44A8768581511);
294 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
295 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200296#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000297 }
298
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200299#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000300 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200301#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000304}
305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200307
308/*
309 * Round constants
310 */
311static const uint64_t K[80] =
312{
313 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
314 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
315 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
316 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
317 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
318 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
319 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
320 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
321 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
322 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
323 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
324 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
325 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
326 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
327 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
328 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
329 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
330 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
331 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
332 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
333 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
334 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
335 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
336 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
337 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
338 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
339 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
340 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
341 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
342 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
343 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
344 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
345 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
346 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
347 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
348 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
349 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
350 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
351 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
352 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
353};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000354#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200355
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000356#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
357 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
358
359#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
360# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
361# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
362#endif
363
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000364/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
365 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
366 */
367
368#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 (__clang_major__ < 13 || \
370 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000371static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
372{
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
374 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000375}
376static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
377{
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
379 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000380}
381static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
382{
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
384 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000385}
386static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
387{
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
389 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000390}
391#endif /* __clang__ etc */
392
393static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000395{
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
397 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
398 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
399 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000400
401 size_t processed = 0;
402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 for (;
404 len >= SHA512_BLOCK_SIZE;
405 processed += SHA512_BLOCK_SIZE,
406 msg += SHA512_BLOCK_SIZE,
407 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000408 uint64x2_t initial_sum, sum, intermed;
409
410 uint64x2_t ab_orig = ab;
411 uint64x2_t cd_orig = cd;
412 uint64x2_t ef_orig = ef;
413 uint64x2_t gh_orig = gh;
414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
416 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
417 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
418 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
419 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
420 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
421 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
422 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000423
424#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
426 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
427 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
428 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
429 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
430 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
431 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
432 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000433#endif
434
435 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
437 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
438 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
439 gh = vsha512h2q_u64(intermed, cd, ab);
440 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000441
442 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
444 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
445 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
446 ef = vsha512h2q_u64(intermed, ab, gh);
447 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000448
449 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
451 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
452 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
453 cd = vsha512h2q_u64(intermed, gh, ef);
454 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000455
456 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
458 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
459 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
460 ab = vsha512h2q_u64(intermed, ef, cd);
461 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000462
463 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
465 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
466 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
467 gh = vsha512h2q_u64(intermed, cd, ab);
468 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000469
470 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
472 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
473 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
474 ef = vsha512h2q_u64(intermed, ab, gh);
475 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000476
477 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
479 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
480 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
481 cd = vsha512h2q_u64(intermed, gh, ef);
482 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000483
484 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
486 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
487 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
488 ab = vsha512h2q_u64(intermed, ef, cd);
489 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000492 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
494 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
495 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
496 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
497 gh = vsha512h2q_u64(intermed, cd, ab);
498 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000499
500 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
502 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
503 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
504 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
505 ef = vsha512h2q_u64(intermed, ab, gh);
506 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000507
508 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
510 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
511 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
512 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
513 cd = vsha512h2q_u64(intermed, gh, ef);
514 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000515
516 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
518 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
519 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
520 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
521 ab = vsha512h2q_u64(intermed, ef, cd);
522 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000523
524 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
526 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
527 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
528 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
529 gh = vsha512h2q_u64(intermed, cd, ab);
530 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000531
532 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
534 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
535 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
536 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
537 ef = vsha512h2q_u64(intermed, ab, gh);
538 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000539
540 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
542 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
543 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
544 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
545 cd = vsha512h2q_u64(intermed, gh, ef);
546 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000547
548 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
550 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
551 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
552 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
553 ab = vsha512h2q_u64(intermed, ef, cd);
554 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000555 }
556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 ab = vaddq_u64(ab, ab_orig);
558 cd = vaddq_u64(cd, cd_orig);
559 ef = vaddq_u64(ef, ef_orig);
560 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000561 }
562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 vst1q_u64(&ctx->state[0], ab);
564 vst1q_u64(&ctx->state[2], cd);
565 vst1q_u64(&ctx->state[4], ef);
566 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000569}
570
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100571#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
572/*
573 * This function is for internal use only if we are building both C and A64
574 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
575 */
576static
577#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100578int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
579 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000580{
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
582 SHA512_BLOCK_SIZE) ==
583 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000584}
585
Jerry Yu92fc5382023-02-16 11:17:11 +0800586#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800587#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800588#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800589#elif defined(__GNUC__)
590#pragma GCC pop_options
591#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800592#undef MBEDTLS_POP_TARGET_PRAGMA
593#endif
594
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000595#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
596
597
598#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
599#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
600#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
601#endif
602
603
604#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
605
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100606#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
607/*
608 * This function is for internal use only if we are building both C and A64
609 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
610 */
611static
612#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100613int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
614 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000615{
616 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200618 uint64_t temp1, temp2, W[80];
619 uint64_t A[8];
620 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Gilles Peskine449bd832023-01-11 14:50:10 +0100622#define SHR(x, n) ((x) >> (n))
623#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
625#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100626#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
629#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
632#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200635 do \
636 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
638 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200639 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200643 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200645
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200646#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 for (i = 0; i < 80; i++) {
648 if (i < 16) {
649 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
650 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200651 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200653 }
654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
656 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200657
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200658 local.temp1 = local.A[7]; local.A[7] = local.A[6];
659 local.A[6] = local.A[5]; local.A[5] = local.A[4];
660 local.A[4] = local.A[3]; local.A[3] = local.A[2];
661 local.A[2] = local.A[1]; local.A[1] = local.A[0];
662 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200663 }
664#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 for (i = 0; i < 16; i++) {
666 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 }
668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200670 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000672 }
673
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 do {
676 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
677 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
678 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
679 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
680 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
681 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
682 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
683 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
684 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
685 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
686 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
687 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
688 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
689 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
690 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
691 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
692 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200693#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200696 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100698
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200699 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100701
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000703}
Jaeden Amero041039f2018-02-19 15:28:08 +0000704
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000705#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
706
707
708#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
709
710static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000712{
713 size_t processed = 0;
714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 while (len >= SHA512_BLOCK_SIZE) {
716 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
717 return 0;
718 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000719
720 data += SHA512_BLOCK_SIZE;
721 len -= SHA512_BLOCK_SIZE;
722
723 processed += SHA512_BLOCK_SIZE;
724 }
725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000727}
728
729#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
730
731
732#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000735{
736 static int done = 0;
737 static int supported = 0;
738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000740 supported = mbedtls_a64_crypto_sha512_determine_support();
741 done = 1;
742 }
743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000745}
746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
748 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000749{
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if (mbedtls_a64_crypto_sha512_has_support()) {
751 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
752 } else {
753 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
754 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000755}
756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
758 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000759{
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if (mbedtls_a64_crypto_sha512_has_support()) {
761 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
762 } else {
763 return mbedtls_internal_sha512_process_c(ctx, data);
764 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000765}
766
767#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
769/*
770 * SHA-512 process buffer
771 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100772int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
773 const unsigned char *input,
774 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000775{
Janos Follath24eed8d2019-11-22 13:21:35 +0000776 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000777 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000778 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 if (ilen == 0) {
781 return 0;
782 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000783
Paul Bakkerb8213a12011-07-11 08:16:18 +0000784 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000785 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000786
Paul Bakker5c2364c2012-10-01 14:41:15 +0000787 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 if (left && ilen >= fill) {
794 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
797 return ret;
798 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100799
Paul Bakker5121ce52009-01-03 21:22:43 +0000800 input += fill;
801 ilen -= fill;
802 left = 0;
803 }
804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000806 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 mbedtls_internal_sha512_process_many(ctx, input, ilen);
808 if (processed < SHA512_BLOCK_SIZE) {
809 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
810 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100811
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000812 input += processed;
813 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000814 }
815
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 if (ilen > 0) {
817 memcpy((void *) (ctx->buffer + left), input, ilen);
818 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000821}
822
Paul Bakker5121ce52009-01-03 21:22:43 +0000823/*
824 * SHA-512 final digest
825 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100826int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
827 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000828{
Janos Follath24eed8d2019-11-22 13:21:35 +0000829 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200830 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000831 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000832
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200833 /*
834 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
835 */
836 used = ctx->total[0] & 0x7F;
837
838 ctx->buffer[used++] = 0x80;
839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200841 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 memset(ctx->buffer + used, 0, 112 - used);
843 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200844 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
848 return ret;
849 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200852 }
853
854 /*
855 * Add message length
856 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 high = (ctx->total[0] >> 61)
858 | (ctx->total[1] << 3);
859 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 sha512_put_uint64_be(high, ctx->buffer, 112);
862 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
865 return ret;
866 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000867
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200868 /*
869 * Output final state
870 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 sha512_put_uint64_be(ctx->state[0], output, 0);
872 sha512_put_uint64_be(ctx->state[1], output, 8);
873 sha512_put_uint64_be(ctx->state[2], output, 16);
874 sha512_put_uint64_be(ctx->state[3], output, 24);
875 sha512_put_uint64_be(ctx->state[4], output, 32);
876 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000877
David Horstmann2788f6b2022-10-06 18:45:09 +0100878 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200879#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100880 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200881#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 if (!truncated) {
883 sha512_put_uint64_be(ctx->state[6], output, 48);
884 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000885 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000888}
889
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200891
Paul Bakker5121ce52009-01-03 21:22:43 +0000892/*
893 * output = SHA-512( input buffer )
894 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100895int mbedtls_sha512(const unsigned char *input,
896 size_t ilen,
897 unsigned char *output,
898 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000899{
Janos Follath24eed8d2019-11-22 13:21:35 +0000900 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
Valerio Setti43363f52022-12-14 08:53:23 +0100903#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100905 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 }
Valerio Setti43363f52022-12-14 08:53:23 +0100907#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100909 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 }
Valerio Setti43363f52022-12-14 08:53:23 +0100911#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100913 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100915#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 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
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100924 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100928 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100930
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100931exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000935}
936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
939/*
940 * FIPS-180-2 test vectors
941 */
Valerio Setti43363f52022-12-14 08:53:23 +0100942static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000943{
944 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 {
946 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
947 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 { "" }
949};
950
Valerio Setti43363f52022-12-14 08:53:23 +0100951static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000952{
953 3, 112, 1000
954};
955
Valerio Setti43363f52022-12-14 08:53:23 +0100956typedef const unsigned char (sha_test_sum_t)[64];
957
958/*
959 * SHA-384 test vectors
960 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200961#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100962static sha_test_sum_t sha384_test_sum[] =
963{
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
965 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
966 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
967 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
968 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
969 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
970 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
971 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
972 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
973 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
974 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
975 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
976 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
977 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
978 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
979 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
980 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100981 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
982};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200983#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000984
Valerio Setti43363f52022-12-14 08:53:23 +0100985/*
986 * SHA-512 test vectors
987 */
988#if defined(MBEDTLS_SHA512_C)
989static sha_test_sum_t sha512_test_sum[] =
990{
Paul Bakker5121ce52009-01-03 21:22:43 +0000991 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
992 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
993 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
994 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
995 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
996 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
997 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
998 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
999 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
1000 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
1001 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
1002 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
1003 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
1004 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
1005 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
1006 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
1007 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
1008 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1009 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1010 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1011 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1012 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1013 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1014 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1015};
Valerio Setti43363f52022-12-14 08:53:23 +01001016#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +02001019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001021{
Valerio Setti43363f52022-12-14 08:53:23 +01001022 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001023 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001024 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001025 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001026
Valerio Setti43363f52022-12-14 08:53:23 +01001027#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001029#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001031#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001033#endif
1034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1036 if (NULL == buf) {
1037 if (verbose != 0) {
1038 mbedtls_printf("Buffer allocation failed\n");
1039 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001042 }
1043
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 for (i = 0; i < 3; i++) {
1047 if (verbose != 0) {
1048 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1049 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001050
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001052 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 if (i == 2) {
1056 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 for (int j = 0; j < 1000; j++) {
1059 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1060 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001061 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 }
1063 }
1064 } else {
1065 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1066 sha_test_buflen[i]);
1067 if (ret != 0) {
1068 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
1072 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1073 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001074 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001075
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001077 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001078 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001079 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001080
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 if (verbose != 0) {
1082 mbedtls_printf("passed\n");
1083 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001084 }
1085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 if (verbose != 0) {
1087 mbedtls_printf("\n");
1088 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001089
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001090 goto exit;
1091
1092fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 if (verbose != 0) {
1094 mbedtls_printf("failed\n");
1095 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001096
Paul Bakker5b4af392014-06-26 12:09:34 +02001097exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 mbedtls_sha512_free(&ctx);
1099 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001100
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001102}
1103
Valerio Setti898e7a32022-12-14 08:55:53 +01001104#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001105int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001106{
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001108}
Valerio Setti898e7a32022-12-14 08:55:53 +01001109#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001110
Valerio Setti898e7a32022-12-14 08:55:53 +01001111#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001112int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001113{
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001115}
Valerio Setti898e7a32022-12-14 08:55:53 +01001116#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001117
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001118#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001121
Valerio Setti43363f52022-12-14 08:53:23 +01001122#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */