blob: 0ea64218b2f38d98347d5151a18fe59518db4af9 [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
David Horstmanne3d8f312023-01-03 11:07:09 +0000107/* *INDENT-OFF* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000108#ifndef asm
109#define asm __asm__
110#endif
David Horstmanne3d8f312023-01-03 11:07:09 +0000111/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000112
113static jmp_buf return_from_sigill;
114
115/*
116 * A64 SHA512 support detection via SIGILL
117 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100118static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000119{
120 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000122}
123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000125{
126 struct sigaction old_action, new_action;
127
128 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 if (sigprocmask(0, NULL, &old_mask)) {
130 return 0;
131 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000132
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000134 new_action.sa_flags = 0;
135 new_action.sa_handler = sigill_handler;
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000138
139 static int ret = 0;
140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000142 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000144 ret = 1;
145 }
146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 sigaction(SIGILL, &old_action, NULL);
148 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000151}
152#else
153#warning "No mechanism to detect A64_CRYPTO found, using C code only"
154#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
155#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
156
157#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
158
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200159#if !defined(MBEDTLS_SHA512_ALT)
160
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000161#define SHA512_BLOCK_SIZE 128
162
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200163#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100164static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200165{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100166 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200167}
168#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100169#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200170#endif /* MBEDTLS_SHA512_SMALLER */
171
Gilles Peskine449bd832023-01-11 14:50:10 +0100172void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200173{
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200175}
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200178{
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200180 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200184}
185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
187 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200188{
189 *dst = *src;
190}
191
Paul Bakker5121ce52009-01-03 21:22:43 +0000192/*
193 * SHA-512 context setup
194 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100195int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000196{
Valerio Setti43363f52022-12-14 08:53:23 +0100197#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100199 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 }
Valerio Setti43363f52022-12-14 08:53:23 +0100201#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100203 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 }
Valerio Setti43363f52022-12-14 08:53:23 +0100205#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100207 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100209#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000210
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 ctx->total[0] = 0;
212 ctx->total[1] = 0;
213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100215#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000216 ctx->state[0] = UL64(0x6A09E667F3BCC908);
217 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
218 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
219 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
220 ctx->state[4] = UL64(0x510E527FADE682D1);
221 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
222 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
223 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100224#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100226#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
228 ctx->state[1] = UL64(0x629A292A367CD507);
229 ctx->state[2] = UL64(0x9159015A3070DD17);
230 ctx->state[3] = UL64(0x152FECD8F70E5939);
231 ctx->state[4] = UL64(0x67332667FFC00B31);
232 ctx->state[5] = UL64(0x8EB44A8768581511);
233 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
234 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200235#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000236 }
237
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200238#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000239 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200240#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100241
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000243}
244
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200246
247/*
248 * Round constants
249 */
250static const uint64_t K[80] =
251{
252 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
253 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
254 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
255 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
256 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
257 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
258 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
259 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
260 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
261 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
262 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
263 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
264 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
265 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
266 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
267 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
268 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
269 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
270 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
271 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
272 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
273 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
274 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
275 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
276 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
277 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
278 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
279 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
280 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
281 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
282 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
283 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
284 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
285 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
286 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
287 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
288 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
289 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
290 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
291 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
292};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000293#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200294
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000295#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
296 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
297
298#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
299# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
300# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
301#endif
302
David Horstmanne3d8f312023-01-03 11:07:09 +0000303/* *INDENT-OFF* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000304#ifndef asm
305#define asm __asm__
306#endif
David Horstmanne3d8f312023-01-03 11:07:09 +0000307/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000308
309/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
310 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
311 */
312
313#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 (__clang_major__ < 13 || \
315 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000316static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
317{
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
319 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000320}
321static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
322{
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
324 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000325}
326static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
327{
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
329 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000330}
331static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
332{
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
334 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000335}
336#endif /* __clang__ etc */
337
338static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000340{
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
342 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
343 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
344 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000345
346 size_t processed = 0;
347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 for (;
349 len >= SHA512_BLOCK_SIZE;
350 processed += SHA512_BLOCK_SIZE,
351 msg += SHA512_BLOCK_SIZE,
352 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000353 uint64x2_t initial_sum, sum, intermed;
354
355 uint64x2_t ab_orig = ab;
356 uint64x2_t cd_orig = cd;
357 uint64x2_t ef_orig = ef;
358 uint64x2_t gh_orig = gh;
359
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
361 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
362 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
363 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
364 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
365 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
366 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
367 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000368
369#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
371 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
372 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
373 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
374 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
375 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
376 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
377 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000378#endif
379
380 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
382 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
383 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
384 gh = vsha512h2q_u64(intermed, cd, ab);
385 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000386
387 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
389 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
390 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
391 ef = vsha512h2q_u64(intermed, ab, gh);
392 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000393
394 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
396 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
397 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
398 cd = vsha512h2q_u64(intermed, gh, ef);
399 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000400
401 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
403 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
404 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
405 ab = vsha512h2q_u64(intermed, ef, cd);
406 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000407
408 /* Rounds 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
410 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
411 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
412 gh = vsha512h2q_u64(intermed, cd, ab);
413 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000414
415 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
417 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
418 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
419 ef = vsha512h2q_u64(intermed, ab, gh);
420 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000421
422 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
424 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
425 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
426 cd = vsha512h2q_u64(intermed, gh, ef);
427 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000428
429 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
431 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
432 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
433 ab = vsha512h2q_u64(intermed, ef, cd);
434 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000437 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
439 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
440 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
441 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
442 gh = vsha512h2q_u64(intermed, cd, ab);
443 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000444
445 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
447 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
448 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
449 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
450 ef = vsha512h2q_u64(intermed, ab, gh);
451 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000452
453 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
455 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
456 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
457 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
458 cd = vsha512h2q_u64(intermed, gh, ef);
459 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000460
461 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
463 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
464 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
465 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
466 ab = vsha512h2q_u64(intermed, ef, cd);
467 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000468
469 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
471 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
472 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
473 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
474 gh = vsha512h2q_u64(intermed, cd, ab);
475 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000476
477 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
479 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
480 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
481 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
482 ef = vsha512h2q_u64(intermed, ab, gh);
483 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000484
485 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
487 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
488 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
489 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
490 cd = vsha512h2q_u64(intermed, gh, ef);
491 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000492
493 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
495 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
496 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
497 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
498 ab = vsha512h2q_u64(intermed, ef, cd);
499 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000500 }
501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 ab = vaddq_u64(ab, ab_orig);
503 cd = vaddq_u64(cd, cd_orig);
504 ef = vaddq_u64(ef, ef_orig);
505 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000506 }
507
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 vst1q_u64(&ctx->state[0], ab);
509 vst1q_u64(&ctx->state[2], cd);
510 vst1q_u64(&ctx->state[4], ef);
511 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000512
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000514}
515
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100516#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
517/*
518 * This function is for internal use only if we are building both C and A64
519 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
520 */
521static
522#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100523int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
524 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000525{
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
527 SHA512_BLOCK_SIZE) ==
528 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000529}
530
531#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
532
533
534#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
535#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
536#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
537#endif
538
539
540#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
541
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100542#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
543/*
544 * This function is for internal use only if we are building both C and A64
545 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
546 */
547static
548#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100549int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
550 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000551{
552 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200554 uint64_t temp1, temp2, W[80];
555 uint64_t A[8];
556 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558#define SHR(x, n) ((x) >> (n))
559#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100562#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
565#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
568#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200571 do \
572 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
574 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200575 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200579 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200581
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200582#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 for (i = 0; i < 80; i++) {
584 if (i < 16) {
585 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
586 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200587 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200589 }
590
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
592 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200593
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200594 local.temp1 = local.A[7]; local.A[7] = local.A[6];
595 local.A[6] = local.A[5]; local.A[5] = local.A[4];
596 local.A[4] = local.A[3]; local.A[3] = local.A[2];
597 local.A[2] = local.A[1]; local.A[1] = local.A[0];
598 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200599 }
600#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 for (i = 0; i < 16; i++) {
602 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000603 }
604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200606 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
609
Paul Bakker5121ce52009-01-03 21:22:43 +0000610 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 do {
612 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
613 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
614 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
615 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
616 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
617 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
618 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
619 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
620 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
621 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
622 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
623 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
624 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
625 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
626 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
627 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
628 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200629#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200632 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100634
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200635 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000639}
Jaeden Amero041039f2018-02-19 15:28:08 +0000640
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000641#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
642
643
644#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
645
646static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000648{
649 size_t processed = 0;
650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 while (len >= SHA512_BLOCK_SIZE) {
652 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
653 return 0;
654 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000655
656 data += SHA512_BLOCK_SIZE;
657 len -= SHA512_BLOCK_SIZE;
658
659 processed += SHA512_BLOCK_SIZE;
660 }
661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000663}
664
665#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
666
667
668#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
669
Gilles Peskine449bd832023-01-11 14:50:10 +0100670static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000671{
672 static int done = 0;
673 static int supported = 0;
674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000676 supported = mbedtls_a64_crypto_sha512_determine_support();
677 done = 1;
678 }
679
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000681}
682
Gilles Peskine449bd832023-01-11 14:50:10 +0100683static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
684 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000685{
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 if (mbedtls_a64_crypto_sha512_has_support()) {
687 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
688 } else {
689 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
690 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000691}
692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
694 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000695{
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 if (mbedtls_a64_crypto_sha512_has_support()) {
697 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
698 } else {
699 return mbedtls_internal_sha512_process_c(ctx, data);
700 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000701}
702
703#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000704
705/*
706 * SHA-512 process buffer
707 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100708int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
709 const unsigned char *input,
710 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000711{
Janos Follath24eed8d2019-11-22 13:21:35 +0000712 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000713 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000714 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 if (ilen == 0) {
717 return 0;
718 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000719
Paul Bakkerb8213a12011-07-11 08:16:18 +0000720 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000721 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
Paul Bakker5c2364c2012-10-01 14:41:15 +0000723 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000726 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000728
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 if (left && ilen >= fill) {
730 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
733 return ret;
734 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100735
Paul Bakker5121ce52009-01-03 21:22:43 +0000736 input += fill;
737 ilen -= fill;
738 left = 0;
739 }
740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000742 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 mbedtls_internal_sha512_process_many(ctx, input, ilen);
744 if (processed < SHA512_BLOCK_SIZE) {
745 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
746 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100747
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000748 input += processed;
749 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 }
751
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 if (ilen > 0) {
753 memcpy((void *) (ctx->buffer + left), input, ilen);
754 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100755
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000757}
758
Paul Bakker5121ce52009-01-03 21:22:43 +0000759/*
760 * SHA-512 final digest
761 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100762int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
763 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000764{
Janos Follath24eed8d2019-11-22 13:21:35 +0000765 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200766 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000767 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200769 /*
770 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
771 */
772 used = ctx->total[0] & 0x7F;
773
774 ctx->buffer[used++] = 0x80;
775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200777 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 memset(ctx->buffer + used, 0, 112 - used);
779 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200780 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200782
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
784 return ret;
785 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200786
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200788 }
789
790 /*
791 * Add message length
792 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 high = (ctx->total[0] >> 61)
794 | (ctx->total[1] << 3);
795 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 sha512_put_uint64_be(high, ctx->buffer, 112);
798 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000799
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
801 return ret;
802 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000803
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200804 /*
805 * Output final state
806 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 sha512_put_uint64_be(ctx->state[0], output, 0);
808 sha512_put_uint64_be(ctx->state[1], output, 8);
809 sha512_put_uint64_be(ctx->state[2], output, 16);
810 sha512_put_uint64_be(ctx->state[3], output, 24);
811 sha512_put_uint64_be(ctx->state[4], output, 32);
812 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
David Horstmann2788f6b2022-10-06 18:45:09 +0100814 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200815#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100816 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200817#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 if (!truncated) {
819 sha512_put_uint64_be(ctx->state[6], output, 48);
820 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000821 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000824}
825
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200827
Paul Bakker5121ce52009-01-03 21:22:43 +0000828/*
829 * output = SHA-512( input buffer )
830 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100831int mbedtls_sha512(const unsigned char *input,
832 size_t ilen,
833 unsigned char *output,
834 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000835{
Janos Follath24eed8d2019-11-22 13:21:35 +0000836 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
Valerio Setti43363f52022-12-14 08:53:23 +0100839#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100841 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 }
Valerio Setti43363f52022-12-14 08:53:23 +0100843#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100845 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 }
Valerio Setti43363f52022-12-14 08:53:23 +0100847#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100849 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100851#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100856 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100860 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100864 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100866
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100867exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000871}
872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000874
875/*
876 * FIPS-180-2 test vectors
877 */
Valerio Setti43363f52022-12-14 08:53:23 +0100878static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000879{
880 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 {
882 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
883 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000884 { "" }
885};
886
Valerio Setti43363f52022-12-14 08:53:23 +0100887static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000888{
889 3, 112, 1000
890};
891
Valerio Setti43363f52022-12-14 08:53:23 +0100892typedef const unsigned char (sha_test_sum_t)[64];
893
894/*
895 * SHA-384 test vectors
896 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200897#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100898static sha_test_sum_t sha384_test_sum[] =
899{
Paul Bakker5121ce52009-01-03 21:22:43 +0000900 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
901 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
902 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
903 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
904 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
905 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
906 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
907 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
908 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
909 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
910 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
911 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
912 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
913 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
914 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
915 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
916 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100917 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
918};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200919#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
Valerio Setti43363f52022-12-14 08:53:23 +0100921/*
922 * SHA-512 test vectors
923 */
924#if defined(MBEDTLS_SHA512_C)
925static sha_test_sum_t sha512_test_sum[] =
926{
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
928 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
929 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
930 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
931 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
932 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
933 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
934 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
935 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
936 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
937 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
938 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
939 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
940 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
941 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
942 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
943 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
944 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
945 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
946 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
947 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
948 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
949 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
950 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
951};
Valerio Setti43363f52022-12-14 08:53:23 +0100952#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000957{
Valerio Setti43363f52022-12-14 08:53:23 +0100958 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500959 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200960 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000962
Valerio Setti43363f52022-12-14 08:53:23 +0100963#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100965#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100967#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100969#endif
970
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 buf = mbedtls_calloc(1024, sizeof(unsigned char));
972 if (NULL == buf) {
973 if (verbose != 0) {
974 mbedtls_printf("Buffer allocation failed\n");
975 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500978 }
979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 for (i = 0; i < 3; i++) {
983 if (verbose != 0) {
984 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
985 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000986
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100988 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 if (i == 2) {
992 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000993
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 for (int j = 0; j < 1000; j++) {
995 ret = mbedtls_sha512_update(&ctx, buf, buflen);
996 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100997 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 }
999 }
1000 } else {
1001 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1002 sha_test_buflen[i]);
1003 if (ret != 0) {
1004 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001005 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001006 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001007
1008 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1009 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001010 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001013 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001014 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001015 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 if (verbose != 0) {
1018 mbedtls_printf("passed\n");
1019 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 }
1021
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 if (verbose != 0) {
1023 mbedtls_printf("\n");
1024 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001026 goto exit;
1027
1028fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 if (verbose != 0) {
1030 mbedtls_printf("failed\n");
1031 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001032
Paul Bakker5b4af392014-06-26 12:09:34 +02001033exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 mbedtls_sha512_free(&ctx);
1035 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001036
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001038}
1039
Valerio Setti898e7a32022-12-14 08:55:53 +01001040#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001041int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001042{
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001044}
Valerio Setti898e7a32022-12-14 08:55:53 +01001045#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001046
Valerio Setti898e7a32022-12-14 08:55:53 +01001047#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001048int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001049{
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001051}
Valerio Setti898e7a32022-12-14 08:55:53 +01001052#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001053
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001054#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001057
Valerio Setti43363f52022-12-14 08:53:23 +01001058#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */