blob: efcbed413ff809a3a174398b26066ff1df571995 [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)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000046# include <arm_neon.h>
47# endif
48# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
49# if defined(__unix__)
50# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010051/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000052# include <sys/auxv.h>
53# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010054/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000055# include <signal.h>
56# endif
57# endif
58#elif defined(_M_ARM64)
59# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010060 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000061# include <arm64_neon.h>
62# endif
63#else
64# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
65# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
66#endif
67
68#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
69/*
70 * Capability detection code comes early, so we can disable
71 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
72 */
73#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +010074static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000075{
Gilles Peskine449bd832023-01-11 14:50:10 +010076 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000077}
78#elif defined(__APPLE__)
79#include <sys/types.h>
80#include <sys/sysctl.h>
81
Gilles Peskine449bd832023-01-11 14:50:10 +010082static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000083{
84 int value = 0;
85 size_t value_len = sizeof(value);
86
Gilles Peskine449bd832023-01-11 14:50:10 +010087 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
88 NULL, 0);
89 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000090}
91#elif defined(_M_ARM64)
92/*
93 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
94 * available to pass to IsProcessorFeaturePresent() to check for
95 * SHA-512 support. So we fall back to the C code only.
96 */
97#if defined(_MSC_VER)
98#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
99#else
100#warning "No mechanism to detect A64_CRYPTO found, using C code only"
101#endif
102#elif defined(__unix__) && defined(SIG_SETMASK)
103/* Detection with SIGILL, setjmp() and longjmp() */
104#include <signal.h>
105#include <setjmp.h>
106
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000107static jmp_buf return_from_sigill;
108
109/*
110 * A64 SHA512 support detection via SIGILL
111 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100112static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000113{
114 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000116}
117
Gilles Peskine449bd832023-01-11 14:50:10 +0100118static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000119{
120 struct sigaction old_action, new_action;
121
122 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 if (sigprocmask(0, NULL, &old_mask)) {
124 return 0;
125 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000128 new_action.sa_flags = 0;
129 new_action.sa_handler = sigill_handler;
130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000132
133 static int ret = 0;
134
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000136 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000138 ret = 1;
139 }
140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 sigaction(SIGILL, &old_action, NULL);
142 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000143
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000145}
146#else
147#warning "No mechanism to detect A64_CRYPTO found, using C code only"
148#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
149#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
150
151#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
152
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200153#if !defined(MBEDTLS_SHA512_ALT)
154
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000155#define SHA512_BLOCK_SIZE 128
156
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200157#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100158static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200159{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100160 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200161}
162#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100163#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200164#endif /* MBEDTLS_SHA512_SMALLER */
165
Gilles Peskine449bd832023-01-11 14:50:10 +0100166void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200167{
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200169}
170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200172{
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200174 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200178}
179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
181 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200182{
183 *dst = *src;
184}
185
Paul Bakker5121ce52009-01-03 21:22:43 +0000186/*
187 * SHA-512 context setup
188 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100189int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000190{
Valerio Setti43363f52022-12-14 08:53:23 +0100191#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100193 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 }
Valerio Setti43363f52022-12-14 08:53:23 +0100195#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100197 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 }
Valerio Setti43363f52022-12-14 08:53:23 +0100199#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100201 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100203#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000204
Paul Bakker5121ce52009-01-03 21:22:43 +0000205 ctx->total[0] = 0;
206 ctx->total[1] = 0;
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100209#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000210 ctx->state[0] = UL64(0x6A09E667F3BCC908);
211 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
212 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
213 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
214 ctx->state[4] = UL64(0x510E527FADE682D1);
215 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
216 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
217 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100218#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100220#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000221 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
222 ctx->state[1] = UL64(0x629A292A367CD507);
223 ctx->state[2] = UL64(0x9159015A3070DD17);
224 ctx->state[3] = UL64(0x152FECD8F70E5939);
225 ctx->state[4] = UL64(0x67332667FFC00B31);
226 ctx->state[5] = UL64(0x8EB44A8768581511);
227 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
228 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200229#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000230 }
231
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200232#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200234#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000237}
238
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200240
241/*
242 * Round constants
243 */
244static const uint64_t K[80] =
245{
246 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
247 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
248 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
249 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
250 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
251 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
252 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
253 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
254 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
255 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
256 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
257 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
258 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
259 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
260 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
261 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
262 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
263 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
264 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
265 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
266 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
267 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
268 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
269 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
270 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
271 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
272 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
273 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
274 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
275 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
276 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
277 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
278 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
279 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
280 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
281 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
282 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
283 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
284 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
285 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
286};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000287#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200288
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000289#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
290 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
291
292#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
293# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
294# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
295#endif
296
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000297/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
298 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
299 */
300
301#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 (__clang_major__ < 13 || \
303 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000304static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
305{
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
307 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000308}
309static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
310{
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
312 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000313}
314static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
315{
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
317 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000318}
319static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
320{
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
322 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000323}
324#endif /* __clang__ etc */
325
326static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000328{
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
330 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
331 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
332 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000333
334 size_t processed = 0;
335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 for (;
337 len >= SHA512_BLOCK_SIZE;
338 processed += SHA512_BLOCK_SIZE,
339 msg += SHA512_BLOCK_SIZE,
340 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000341 uint64x2_t initial_sum, sum, intermed;
342
343 uint64x2_t ab_orig = ab;
344 uint64x2_t cd_orig = cd;
345 uint64x2_t ef_orig = ef;
346 uint64x2_t gh_orig = gh;
347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
349 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
350 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
351 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
352 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
353 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
354 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
355 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000356
357#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
359 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
360 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
361 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
362 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
363 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
364 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
365 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000366#endif
367
368 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
370 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
371 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
372 gh = vsha512h2q_u64(intermed, cd, ab);
373 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000374
375 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
377 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
378 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
379 ef = vsha512h2q_u64(intermed, ab, gh);
380 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000381
382 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
384 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
385 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
386 cd = vsha512h2q_u64(intermed, gh, ef);
387 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000388
389 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
391 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
392 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
393 ab = vsha512h2q_u64(intermed, ef, cd);
394 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000395
396 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
398 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
399 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
400 gh = vsha512h2q_u64(intermed, cd, ab);
401 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000402
403 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
405 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
406 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
407 ef = vsha512h2q_u64(intermed, ab, gh);
408 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000409
410 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
412 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
413 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
414 cd = vsha512h2q_u64(intermed, gh, ef);
415 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000416
417 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
419 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
420 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
421 ab = vsha512h2q_u64(intermed, ef, cd);
422 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000423
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000425 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
427 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
428 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
429 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
430 gh = vsha512h2q_u64(intermed, cd, ab);
431 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000432
433 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
435 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
436 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
437 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
438 ef = vsha512h2q_u64(intermed, ab, gh);
439 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000440
441 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
443 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
444 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
445 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
446 cd = vsha512h2q_u64(intermed, gh, ef);
447 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000448
449 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
451 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
452 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
453 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
454 ab = vsha512h2q_u64(intermed, ef, cd);
455 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000456
457 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
459 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
460 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
461 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
462 gh = vsha512h2q_u64(intermed, cd, ab);
463 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000464
465 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
467 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
468 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
469 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
470 ef = vsha512h2q_u64(intermed, ab, gh);
471 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000472
473 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
475 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
476 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
477 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
478 cd = vsha512h2q_u64(intermed, gh, ef);
479 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000480
481 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
483 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
484 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
485 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
486 ab = vsha512h2q_u64(intermed, ef, cd);
487 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000488 }
489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 ab = vaddq_u64(ab, ab_orig);
491 cd = vaddq_u64(cd, cd_orig);
492 ef = vaddq_u64(ef, ef_orig);
493 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000494 }
495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 vst1q_u64(&ctx->state[0], ab);
497 vst1q_u64(&ctx->state[2], cd);
498 vst1q_u64(&ctx->state[4], ef);
499 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000500
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000502}
503
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100504#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
505/*
506 * This function is for internal use only if we are building both C and A64
507 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
508 */
509static
510#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100511int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
512 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000513{
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
515 SHA512_BLOCK_SIZE) ==
516 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000517}
518
519#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
520
521
522#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
523#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
524#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
525#endif
526
527
528#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
529
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100530#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
531/*
532 * This function is for internal use only if we are building both C and A64
533 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
534 */
535static
536#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100537int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
538 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000539{
540 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200542 uint64_t temp1, temp2, W[80];
543 uint64_t A[8];
544 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546#define SHR(x, n) ((x) >> (n))
547#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000548
549#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100550#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
553#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
556#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200559 do \
560 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
562 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200563 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200567 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200569
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200570#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 for (i = 0; i < 80; i++) {
572 if (i < 16) {
573 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
574 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200575 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200577 }
578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
580 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200581
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200582 local.temp1 = local.A[7]; local.A[7] = local.A[6];
583 local.A[6] = local.A[5]; local.A[5] = local.A[4];
584 local.A[4] = local.A[3]; local.A[3] = local.A[2];
585 local.A[2] = local.A[1]; local.A[1] = local.A[0];
586 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200587 }
588#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 for (i = 0; i < 16; i++) {
590 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000591 }
592
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200594 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 }
597
Paul Bakker5121ce52009-01-03 21:22:43 +0000598 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 do {
600 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
601 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
602 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
603 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
604 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
605 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
606 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
607 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
608 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
609 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
610 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
611 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
612 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
613 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
614 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
615 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
616 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200617#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200620 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100622
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200623 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627}
Jaeden Amero041039f2018-02-19 15:28:08 +0000628
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000629#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
630
631
632#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
633
634static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000636{
637 size_t processed = 0;
638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 while (len >= SHA512_BLOCK_SIZE) {
640 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
641 return 0;
642 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000643
644 data += SHA512_BLOCK_SIZE;
645 len -= SHA512_BLOCK_SIZE;
646
647 processed += SHA512_BLOCK_SIZE;
648 }
649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000651}
652
653#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
654
655
656#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000659{
660 static int done = 0;
661 static int supported = 0;
662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000664 supported = mbedtls_a64_crypto_sha512_determine_support();
665 done = 1;
666 }
667
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000669}
670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
672 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000673{
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 if (mbedtls_a64_crypto_sha512_has_support()) {
675 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
676 } else {
677 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
678 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000679}
680
Gilles Peskine449bd832023-01-11 14:50:10 +0100681int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
682 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000683{
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 if (mbedtls_a64_crypto_sha512_has_support()) {
685 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
686 } else {
687 return mbedtls_internal_sha512_process_c(ctx, data);
688 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000689}
690
691#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
693/*
694 * SHA-512 process buffer
695 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100696int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
697 const unsigned char *input,
698 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000699{
Janos Follath24eed8d2019-11-22 13:21:35 +0000700 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000701 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000702 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000703
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 if (ilen == 0) {
705 return 0;
706 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000707
Paul Bakkerb8213a12011-07-11 08:16:18 +0000708 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000709 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Paul Bakker5c2364c2012-10-01 14:41:15 +0000711 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000714 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 if (left && ilen >= fill) {
718 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100719
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
721 return ret;
722 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100723
Paul Bakker5121ce52009-01-03 21:22:43 +0000724 input += fill;
725 ilen -= fill;
726 left = 0;
727 }
728
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000730 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 mbedtls_internal_sha512_process_many(ctx, input, ilen);
732 if (processed < SHA512_BLOCK_SIZE) {
733 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
734 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100735
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000736 input += processed;
737 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000738 }
739
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 if (ilen > 0) {
741 memcpy((void *) (ctx->buffer + left), input, ilen);
742 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000745}
746
Paul Bakker5121ce52009-01-03 21:22:43 +0000747/*
748 * SHA-512 final digest
749 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100750int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
751 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000752{
Janos Follath24eed8d2019-11-22 13:21:35 +0000753 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200754 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000755 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000756
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200757 /*
758 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
759 */
760 used = ctx->total[0] & 0x7F;
761
762 ctx->buffer[used++] = 0x80;
763
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200765 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 memset(ctx->buffer + used, 0, 112 - used);
767 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200768 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200770
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
772 return ret;
773 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200776 }
777
778 /*
779 * Add message length
780 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 high = (ctx->total[0] >> 61)
782 | (ctx->total[1] << 3);
783 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000784
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 sha512_put_uint64_be(high, ctx->buffer, 112);
786 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000787
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
789 return ret;
790 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000791
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200792 /*
793 * Output final state
794 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 sha512_put_uint64_be(ctx->state[0], output, 0);
796 sha512_put_uint64_be(ctx->state[1], output, 8);
797 sha512_put_uint64_be(ctx->state[2], output, 16);
798 sha512_put_uint64_be(ctx->state[3], output, 24);
799 sha512_put_uint64_be(ctx->state[4], output, 32);
800 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000801
David Horstmann2788f6b2022-10-06 18:45:09 +0100802 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200803#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100804 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200805#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 if (!truncated) {
807 sha512_put_uint64_be(ctx->state[6], output, 48);
808 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000809 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100810
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000812}
813
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200814#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200815
Paul Bakker5121ce52009-01-03 21:22:43 +0000816/*
817 * output = SHA-512( input buffer )
818 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100819int mbedtls_sha512(const unsigned char *input,
820 size_t ilen,
821 unsigned char *output,
822 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000823{
Janos Follath24eed8d2019-11-22 13:21:35 +0000824 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
Valerio Setti43363f52022-12-14 08:53:23 +0100827#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100829 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 }
Valerio Setti43363f52022-12-14 08:53:23 +0100831#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100833 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 }
Valerio Setti43363f52022-12-14 08:53:23 +0100835#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100837 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100839#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100842
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100844 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100848 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100852 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100854
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100855exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100857
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000859}
860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
863/*
864 * FIPS-180-2 test vectors
865 */
Valerio Setti43363f52022-12-14 08:53:23 +0100866static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000867{
868 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 {
870 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
871 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000872 { "" }
873};
874
Valerio Setti43363f52022-12-14 08:53:23 +0100875static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000876{
877 3, 112, 1000
878};
879
Valerio Setti43363f52022-12-14 08:53:23 +0100880typedef const unsigned char (sha_test_sum_t)[64];
881
882/*
883 * SHA-384 test vectors
884 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200885#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100886static sha_test_sum_t sha384_test_sum[] =
887{
Paul Bakker5121ce52009-01-03 21:22:43 +0000888 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
889 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
890 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
891 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
892 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
893 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
894 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
895 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
896 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
897 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
898 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
899 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
900 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
901 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
902 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
903 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
904 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100905 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
906};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200907#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Valerio Setti43363f52022-12-14 08:53:23 +0100909/*
910 * SHA-512 test vectors
911 */
912#if defined(MBEDTLS_SHA512_C)
913static sha_test_sum_t sha512_test_sum[] =
914{
Paul Bakker5121ce52009-01-03 21:22:43 +0000915 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
916 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
917 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
918 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
919 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
920 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
921 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
922 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
923 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
924 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
925 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
926 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
927 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
928 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
929 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
930 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
931 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
932 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
933 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
934 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
935 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
936 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
937 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
938 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
939};
Valerio Setti43363f52022-12-14 08:53:23 +0100940#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000945{
Valerio Setti43363f52022-12-14 08:53:23 +0100946 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500947 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200948 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000950
Valerio Setti43363f52022-12-14 08:53:23 +0100951#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100953#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100955#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100957#endif
958
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 buf = mbedtls_calloc(1024, sizeof(unsigned char));
960 if (NULL == buf) {
961 if (verbose != 0) {
962 mbedtls_printf("Buffer allocation failed\n");
963 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500966 }
967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 for (i = 0; i < 3; i++) {
971 if (verbose != 0) {
972 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
973 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100976 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 if (i == 2) {
980 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 for (int j = 0; j < 1000; j++) {
983 ret = mbedtls_sha512_update(&ctx, buf, buflen);
984 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100985 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 }
987 }
988 } else {
989 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
990 sha_test_buflen[i]);
991 if (ret != 0) {
992 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100993 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000994 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100995
996 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
997 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100998 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001001 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001002 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001003 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 if (verbose != 0) {
1006 mbedtls_printf("passed\n");
1007 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 }
1009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 if (verbose != 0) {
1011 mbedtls_printf("\n");
1012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001013
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001014 goto exit;
1015
1016fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 if (verbose != 0) {
1018 mbedtls_printf("failed\n");
1019 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001020
Paul Bakker5b4af392014-06-26 12:09:34 +02001021exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 mbedtls_sha512_free(&ctx);
1023 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001026}
1027
Valerio Setti898e7a32022-12-14 08:55:53 +01001028#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001029int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001030{
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001032}
Valerio Setti898e7a32022-12-14 08:55:53 +01001033#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001034
Valerio Setti898e7a32022-12-14 08:55:53 +01001035#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001036int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001037{
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001039}
Valerio Setti898e7a32022-12-14 08:55:53 +01001040#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001041
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001042#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001045
Valerio Setti43363f52022-12-14 08:53:23 +01001046#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */