blob: bc92a8de21e6bdc205a0bcf6bff26e7f8a671a23 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Jerry Yua135dee2023-02-16 16:56:22 +080025#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
26 defined(__clang__) && __clang_major__ < 18 && \
27 __clang_major__ >= 13 && __clang_minor__ > 0 && __clang_patchlevel__ > 0
28/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
29 *
Jerry Yufc2e1282023-02-27 11:16:56 +080030 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
31 * these are normally only enabled by the -march option on the command line.
32 * By defining the macros ourselves we gain access to those declarations without
33 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080034 *
Jerry Yufc2e1282023-02-27 11:16:56 +080035 * `arm_neon.h` could be included by any header file, so we put these defines
36 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080037 */
38#define __ARM_FEATURE_SHA512 1
Jerry Yu4d786a72023-02-22 11:01:07 +080039#define NEED_TARGET_OPTIONS
Jerry Yua135dee2023-02-16 16:56:22 +080040#endif /* __aarch64__ && __clang__ &&
Jerry Yuba4ec242023-02-21 15:59:13 +080041 !__ARM_FEATURE_SHA512 && __clang_major__ < 18 &&
42 __clang_major__ >= 13 && __clang_minor__ > 0 &&
43 __clang_patchlevel__ > 0 */
Jerry Yua135dee2023-02-16 16:56:22 +080044
Gilles Peskinedb09ef62020-06-03 01:43:33 +020045#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000046
Valerio Setti43363f52022-12-14 08:53:23 +010047#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000048
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000049#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050050#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000051#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000052
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000053#if defined(_MSC_VER) || defined(__WATCOMC__)
54 #define UL64(x) x##ui64
55#else
56 #define UL64(x) x##ULL
57#endif
58
Rich Evans00ab4702015-02-06 13:43:58 +000059#include <string.h>
60
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010062
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000063#if defined(__aarch64__)
64# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010065 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080066/* *INDENT-OFF* */
67/*
68 * Best performance comes from most recent compilers, with intrinsics and -O3.
69 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
70 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
71 *
72 * GCC < 8 won't work at all (lacks the sha512 instructions)
73 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
74 *
75 * Clang < 7 won't work at all (lacks the sha512 instructions)
76 * Clang 7-12 don't have intrinsics (but we work around that with inline
77 * assembler) or __ARM_FEATURE_SHA512
78 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
79 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
80 */
Jerry Yu4d786a72023-02-22 11:01:07 +080081# if !defined(__ARM_FEATURE_SHA512) || defined(NEED_TARGET_OPTIONS)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080082 /* Test Clang first, as it defines __GNUC__ */
83# if defined(__clang__)
84# if __clang_major__ < 7
85# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
86# elif __clang_major__ < 13 || \
87 (__clang_major__ == 13 && __clang_minor__ == 0 && \
88 __clang_patchlevel__ == 0)
89 /* We implement the intrinsics with inline assembler, so don't error */
90# else
Jerry Yu64e5d4a2023-02-15 11:46:57 +080091# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
92# define MBEDTLS_POP_TARGET_PRAGMA
93# endif
94# elif defined(__GNUC__)
95# if __GNUC__ < 8
96# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
97# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080098# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080099# pragma GCC target ("arch=armv8.2-a+sha3")
Jerry Yu2f2c0492023-02-16 14:24:46 +0800100# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800101# endif
102# else
103# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
104# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800105# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800106/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000107# include <arm_neon.h>
108# endif
109# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
110# if defined(__unix__)
111# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100112/* Our preferred method of detection is getauxval() */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000113# include <sys/auxv.h>
114# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100115/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000116# include <signal.h>
117# endif
118# endif
119#elif defined(_M_ARM64)
120# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000122# include <arm64_neon.h>
123# endif
124#else
125# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
126# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
127#endif
128
129#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
130/*
131 * Capability detection code comes early, so we can disable
132 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
133 */
134#if defined(HWCAP_SHA512)
Gilles Peskine449bd832023-01-11 14:50:10 +0100135static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000136{
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000138}
139#elif defined(__APPLE__)
140#include <sys/types.h>
141#include <sys/sysctl.h>
142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000144{
145 int value = 0;
146 size_t value_len = sizeof(value);
147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
149 NULL, 0);
150 return ret == 0 && value != 0;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000151}
152#elif defined(_M_ARM64)
153/*
154 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
155 * available to pass to IsProcessorFeaturePresent() to check for
156 * SHA-512 support. So we fall back to the C code only.
157 */
158#if defined(_MSC_VER)
159#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
160#else
161#warning "No mechanism to detect A64_CRYPTO found, using C code only"
162#endif
163#elif defined(__unix__) && defined(SIG_SETMASK)
164/* Detection with SIGILL, setjmp() and longjmp() */
165#include <signal.h>
166#include <setjmp.h>
167
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000168static jmp_buf return_from_sigill;
169
170/*
171 * A64 SHA512 support detection via SIGILL
172 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100173static void sigill_handler(int signal)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000174{
175 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 longjmp(return_from_sigill, 1);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000177}
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179static int mbedtls_a64_crypto_sha512_determine_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000180{
181 struct sigaction old_action, new_action;
182
183 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 if (sigprocmask(0, NULL, &old_mask)) {
185 return 0;
186 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 sigemptyset(&new_action.sa_mask);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000189 new_action.sa_flags = 0;
190 new_action.sa_handler = sigill_handler;
191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000193
194 static int ret = 0;
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000197 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 asm ("sha512h q0, q0, v0.2d" : : : "v0");
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000199 ret = 1;
200 }
201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 sigaction(SIGILL, &old_action, NULL);
203 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 return ret;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000206}
207#else
208#warning "No mechanism to detect A64_CRYPTO found, using C code only"
209#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
210#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
211
212#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
213
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200214#if !defined(MBEDTLS_SHA512_ALT)
215
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000216#define SHA512_BLOCK_SIZE 128
217
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200218#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100219static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200220{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100221 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200222}
223#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100224#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200225#endif /* MBEDTLS_SHA512_SMALLER */
226
Gilles Peskine449bd832023-01-11 14:50:10 +0100227void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200228{
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200230}
231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200233{
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200235 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200237
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200239}
240
Gilles Peskine449bd832023-01-11 14:50:10 +0100241void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
242 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200243{
244 *dst = *src;
245}
246
Paul Bakker5121ce52009-01-03 21:22:43 +0000247/*
248 * SHA-512 context setup
249 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100250int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000251{
Valerio Setti43363f52022-12-14 08:53:23 +0100252#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100254 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 }
Valerio Setti43363f52022-12-14 08:53:23 +0100256#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100258 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 }
Valerio Setti43363f52022-12-14 08:53:23 +0100260#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100262 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100264#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000265
Paul Bakker5121ce52009-01-03 21:22:43 +0000266 ctx->total[0] = 0;
267 ctx->total[1] = 0;
268
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100270#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 ctx->state[0] = UL64(0x6A09E667F3BCC908);
272 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
273 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
274 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
275 ctx->state[4] = UL64(0x510E527FADE682D1);
276 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
277 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
278 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100279#endif /* MBEDTLS_SHA512_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 } else {
Valerio Setti43363f52022-12-14 08:53:23 +0100281#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000282 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
283 ctx->state[1] = UL64(0x629A292A367CD507);
284 ctx->state[2] = UL64(0x9159015A3070DD17);
285 ctx->state[3] = UL64(0x152FECD8F70E5939);
286 ctx->state[4] = UL64(0x67332667FFC00B31);
287 ctx->state[5] = UL64(0x8EB44A8768581511);
288 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
289 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200290#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 }
292
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200293#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200295#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000298}
299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200301
302/*
303 * Round constants
304 */
305static const uint64_t K[80] =
306{
307 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
308 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
309 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
310 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
311 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
312 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
313 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
314 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
315 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
316 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
317 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
318 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
319 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
320 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
321 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
322 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
323 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
324 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
325 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
326 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
327 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
328 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
329 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
330 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
331 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
332 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
333 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
334 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
335 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
336 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
337 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
338 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
339 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
340 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
341 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
342 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
343 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
344 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
345 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
346 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
347};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000348#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200349
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000350#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
351 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
352
353#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
354# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
355# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
356#endif
357
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000358/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
359 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
360 */
361
362#if defined(__clang__) && \
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 (__clang_major__ < 13 || \
364 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000365static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
366{
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
368 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000369}
370static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
371{
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
373 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000374}
375static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
376{
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
378 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000379}
380static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
381{
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
383 return x;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000384}
385#endif /* __clang__ etc */
386
387static size_t mbedtls_internal_sha512_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000389{
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
391 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
392 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
393 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000394
395 size_t processed = 0;
396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 for (;
398 len >= SHA512_BLOCK_SIZE;
399 processed += SHA512_BLOCK_SIZE,
400 msg += SHA512_BLOCK_SIZE,
401 len -= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000402 uint64x2_t initial_sum, sum, intermed;
403
404 uint64x2_t ab_orig = ab;
405 uint64x2_t cd_orig = cd;
406 uint64x2_t ef_orig = ef;
407 uint64x2_t gh_orig = gh;
408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
410 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
411 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
412 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
413 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
414 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
415 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
416 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000417
418#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
420 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
421 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
422 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
423 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
424 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
425 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
426 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000427#endif
428
429 /* Rounds 0 and 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
431 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
432 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
433 gh = vsha512h2q_u64(intermed, cd, ab);
434 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000435
436 /* Rounds 2 and 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
438 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
439 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
440 ef = vsha512h2q_u64(intermed, ab, gh);
441 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000442
443 /* Rounds 4 and 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
445 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
446 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
447 cd = vsha512h2q_u64(intermed, gh, ef);
448 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000449
450 /* Rounds 6 and 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 initial_sum = vaddq_u64(s3, vld1q_u64(&K[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 8 and 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
459 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
460 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
461 gh = vsha512h2q_u64(intermed, cd, ab);
462 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000463
464 /* Rounds 10 and 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
466 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
467 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
468 ef = vsha512h2q_u64(intermed, ab, gh);
469 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000470
471 /* Rounds 12 and 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
473 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
474 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
475 cd = vsha512h2q_u64(intermed, gh, ef);
476 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000477
478 /* Rounds 14 and 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
480 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
481 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
482 ab = vsha512h2q_u64(intermed, ef, cd);
483 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 for (unsigned int t = 16; t < 80; t += 16) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000486 /* Rounds t and t + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
488 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
489 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
490 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
491 gh = vsha512h2q_u64(intermed, cd, ab);
492 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000493
494 /* Rounds t + 2 and t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
496 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
497 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
498 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
499 ef = vsha512h2q_u64(intermed, ab, gh);
500 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000501
502 /* Rounds t + 4 and t + 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
504 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
505 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
506 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
507 cd = vsha512h2q_u64(intermed, gh, ef);
508 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000509
510 /* Rounds t + 6 and t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
512 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
513 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
514 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
515 ab = vsha512h2q_u64(intermed, ef, cd);
516 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000517
518 /* Rounds t + 8 and t + 9 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
520 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
521 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
522 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
523 gh = vsha512h2q_u64(intermed, cd, ab);
524 cd = vaddq_u64(cd, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000525
526 /* Rounds t + 10 and t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
528 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
529 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
530 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
531 ef = vsha512h2q_u64(intermed, ab, gh);
532 ab = vaddq_u64(ab, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000533
534 /* Rounds t + 12 and t + 13 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
536 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
537 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
538 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
539 cd = vsha512h2q_u64(intermed, gh, ef);
540 gh = vaddq_u64(gh, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000541
542 /* Rounds t + 14 and t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
544 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
545 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
546 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
547 ab = vsha512h2q_u64(intermed, ef, cd);
548 ef = vaddq_u64(ef, intermed);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000549 }
550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 ab = vaddq_u64(ab, ab_orig);
552 cd = vaddq_u64(cd, cd_orig);
553 ef = vaddq_u64(ef, ef_orig);
554 gh = vaddq_u64(gh, gh_orig);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000555 }
556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 vst1q_u64(&ctx->state[0], ab);
558 vst1q_u64(&ctx->state[2], cd);
559 vst1q_u64(&ctx->state[4], ef);
560 vst1q_u64(&ctx->state[6], gh);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000563}
564
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100565#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
566/*
567 * This function is for internal use only if we are building both C and A64
568 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
569 */
570static
571#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100572int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
573 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000574{
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
576 SHA512_BLOCK_SIZE) ==
577 SHA512_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000578}
579
Jerry Yu92fc5382023-02-16 11:17:11 +0800580#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800581#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800582#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800583#elif defined(__GNUC__)
584#pragma GCC pop_options
585#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800586#undef MBEDTLS_POP_TARGET_PRAGMA
587#endif
588
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000589#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
590
591
592#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
593#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
594#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
595#endif
596
597
598#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
599
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100600#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
601/*
602 * This function is for internal use only if we are building both C and A64
603 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
604 */
605static
606#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100607int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
608 const unsigned char data[SHA512_BLOCK_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000609{
610 int i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200612 uint64_t temp1, temp2, W[80];
613 uint64_t A[8];
614 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616#define SHR(x, n) ((x) >> (n))
617#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Gilles Peskine449bd832023-01-11 14:50:10 +0100620#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Gilles Peskine449bd832023-01-11 14:50:10 +0100622#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
623#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
626#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200629 do \
630 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
632 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200633 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200637 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 }
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200639
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200640#if defined(MBEDTLS_SHA512_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 for (i = 0; i < 80; i++) {
642 if (i < 16) {
643 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
644 } else {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200645 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200647 }
648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
650 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200651
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200652 local.temp1 = local.A[7]; local.A[7] = local.A[6];
653 local.A[6] = local.A[5]; local.A[5] = local.A[4];
654 local.A[4] = local.A[3]; local.A[3] = local.A[2];
655 local.A[2] = local.A[1]; local.A[1] = local.A[0];
656 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200657 }
658#else /* MBEDTLS_SHA512_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 for (i = 0; i < 16; i++) {
660 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 }
662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 for (; i < 80; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200664 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 }
667
Paul Bakker5121ce52009-01-03 21:22:43 +0000668 i = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 do {
670 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
671 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
672 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
673 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
674 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
675 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
676 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
677 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
678 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
679 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
680 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
681 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
682 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
683 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
684 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
685 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
686 } while (i < 80);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200687#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200690 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100692
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200693 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100695
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000697}
Jaeden Amero041039f2018-02-19 15:28:08 +0000698
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000699#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
700
701
702#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
703
704static size_t mbedtls_internal_sha512_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000706{
707 size_t processed = 0;
708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 while (len >= SHA512_BLOCK_SIZE) {
710 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
711 return 0;
712 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000713
714 data += SHA512_BLOCK_SIZE;
715 len -= SHA512_BLOCK_SIZE;
716
717 processed += SHA512_BLOCK_SIZE;
718 }
719
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 return processed;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000721}
722
723#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
724
725
726#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
727
Gilles Peskine449bd832023-01-11 14:50:10 +0100728static int mbedtls_a64_crypto_sha512_has_support(void)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000729{
730 static int done = 0;
731 static int supported = 0;
732
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 if (!done) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000734 supported = mbedtls_a64_crypto_sha512_determine_support();
735 done = 1;
736 }
737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 return supported;
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000739}
740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
742 const uint8_t *msg, size_t len)
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000743{
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 if (mbedtls_a64_crypto_sha512_has_support()) {
745 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
746 } else {
747 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
748 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000749}
750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
752 const unsigned char data[SHA512_BLOCK_SIZE])
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000753{
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 if (mbedtls_a64_crypto_sha512_has_support()) {
755 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
756 } else {
757 return mbedtls_internal_sha512_process_c(ctx, data);
758 }
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000759}
760
761#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000762
763/*
764 * SHA-512 process buffer
765 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100766int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
767 const unsigned char *input,
768 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000769{
Janos Follath24eed8d2019-11-22 13:21:35 +0000770 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000771 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000772 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 if (ilen == 0) {
775 return 0;
776 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000777
Paul Bakkerb8213a12011-07-11 08:16:18 +0000778 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000779 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
Paul Bakker5c2364c2012-10-01 14:41:15 +0000781 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000782
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 if (ctx->total[0] < (uint64_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000784 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000786
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 if (left && ilen >= fill) {
788 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
791 return ret;
792 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100793
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 input += fill;
795 ilen -= fill;
796 left = 0;
797 }
798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 while (ilen >= SHA512_BLOCK_SIZE) {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000800 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 mbedtls_internal_sha512_process_many(ctx, input, ilen);
802 if (processed < SHA512_BLOCK_SIZE) {
803 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
804 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100805
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000806 input += processed;
807 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000808 }
809
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 if (ilen > 0) {
811 memcpy((void *) (ctx->buffer + left), input, ilen);
812 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000815}
816
Paul Bakker5121ce52009-01-03 21:22:43 +0000817/*
818 * SHA-512 final digest
819 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100820int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
821 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000822{
Janos Follath24eed8d2019-11-22 13:21:35 +0000823 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200824 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000825 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200827 /*
828 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
829 */
830 used = ctx->total[0] & 0x7F;
831
832 ctx->buffer[used++] = 0x80;
833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200835 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 memset(ctx->buffer + used, 0, 112 - used);
837 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200838 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
842 return ret;
843 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200846 }
847
848 /*
849 * Add message length
850 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 high = (ctx->total[0] >> 61)
852 | (ctx->total[1] << 3);
853 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 sha512_put_uint64_be(high, ctx->buffer, 112);
856 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000857
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
859 return ret;
860 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200862 /*
863 * Output final state
864 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 sha512_put_uint64_be(ctx->state[0], output, 0);
866 sha512_put_uint64_be(ctx->state[1], output, 8);
867 sha512_put_uint64_be(ctx->state[2], output, 16);
868 sha512_put_uint64_be(ctx->state[3], output, 24);
869 sha512_put_uint64_be(ctx->state[4], output, 32);
870 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000871
David Horstmann2788f6b2022-10-06 18:45:09 +0100872 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200873#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100874 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200875#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 if (!truncated) {
877 sha512_put_uint64_be(ctx->state[6], output, 48);
878 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000879 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100880
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000882}
883
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200885
Paul Bakker5121ce52009-01-03 21:22:43 +0000886/*
887 * output = SHA-512( input buffer )
888 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100889int mbedtls_sha512(const unsigned char *input,
890 size_t ilen,
891 unsigned char *output,
892 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000893{
Janos Follath24eed8d2019-11-22 13:21:35 +0000894 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000896
Valerio Setti43363f52022-12-14 08:53:23 +0100897#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 if (is384 != 0 && is384 != 1) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100899 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 }
Valerio Setti43363f52022-12-14 08:53:23 +0100901#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 if (is384 != 0) {
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100903 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 }
Valerio Setti43363f52022-12-14 08:53:23 +0100905#else /* defined MBEDTLS_SHA384_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 if (is384 == 0) {
Valerio Setti43363f52022-12-14 08:53:23 +0100907 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 }
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100909#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100914 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100918 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100922 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100924
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100925exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100927
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000929}
930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000932
933/*
934 * FIPS-180-2 test vectors
935 */
Valerio Setti43363f52022-12-14 08:53:23 +0100936static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000937{
938 { "abc" },
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 {
940 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
941 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000942 { "" }
943};
944
Valerio Setti43363f52022-12-14 08:53:23 +0100945static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000946{
947 3, 112, 1000
948};
949
Valerio Setti43363f52022-12-14 08:53:23 +0100950typedef const unsigned char (sha_test_sum_t)[64];
951
952/*
953 * SHA-384 test vectors
954 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200955#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100956static sha_test_sum_t sha384_test_sum[] =
957{
Paul Bakker5121ce52009-01-03 21:22:43 +0000958 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
959 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
960 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
961 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
962 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
963 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
964 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
965 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
966 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
967 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
968 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
969 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
970 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
971 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
972 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
973 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
974 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100975 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
976};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200977#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000978
Valerio Setti43363f52022-12-14 08:53:23 +0100979/*
980 * SHA-512 test vectors
981 */
982#if defined(MBEDTLS_SHA512_C)
983static sha_test_sum_t sha512_test_sum[] =
984{
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
986 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
987 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
988 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
989 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
990 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
991 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
992 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
993 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
994 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
995 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
996 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
997 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
998 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
999 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
1000 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
1001 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
1002 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
1003 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
1004 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
1005 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
1006 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
1007 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1008 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1009};
Valerio Setti43363f52022-12-14 08:53:23 +01001010#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +02001013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014static int mbedtls_sha512_common_self_test(int verbose, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +00001015{
Valerio Setti43363f52022-12-14 08:53:23 +01001016 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -05001017 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +02001018 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
Valerio Setti43363f52022-12-14 08:53:23 +01001021#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001023#elif defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001025#else
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +01001027#endif
1028
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1030 if (NULL == buf) {
1031 if (verbose != 0) {
1032 mbedtls_printf("Buffer allocation failed\n");
1033 }
Russ Butlerbb83b422016-10-12 17:36:50 -05001034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -05001036 }
1037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +02001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 for (i = 0; i < 3; i++) {
1041 if (verbose != 0) {
1042 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1043 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001046 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 if (i == 2) {
1050 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 for (int j = 0; j < 1000; j++) {
1053 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1054 if (ret != 0) {
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001055 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 }
1057 }
1058 } else {
1059 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1060 sha_test_buflen[i]);
1061 if (ret != 0) {
1062 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001063 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001064 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001065
1066 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1067 goto fail;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001068 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001071 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001072 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001073 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001074
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 if (verbose != 0) {
1076 mbedtls_printf("passed\n");
1077 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001078 }
1079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 if (verbose != 0) {
1081 mbedtls_printf("\n");
1082 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001083
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001084 goto exit;
1085
1086fail:
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 if (verbose != 0) {
1088 mbedtls_printf("failed\n");
1089 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001090
Paul Bakker5b4af392014-06-26 12:09:34 +02001091exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 mbedtls_sha512_free(&ctx);
1093 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +02001094
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001096}
1097
Valerio Setti898e7a32022-12-14 08:55:53 +01001098#if defined(MBEDTLS_SHA512_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001099int mbedtls_sha512_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001100{
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 return mbedtls_sha512_common_self_test(verbose, 0);
Valerio Setti43363f52022-12-14 08:53:23 +01001102}
Valerio Setti898e7a32022-12-14 08:55:53 +01001103#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001104
Valerio Setti898e7a32022-12-14 08:55:53 +01001105#if defined(MBEDTLS_SHA384_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001106int mbedtls_sha384_self_test(int verbose)
Valerio Setti43363f52022-12-14 08:53:23 +01001107{
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 return mbedtls_sha512_common_self_test(verbose, 1);
Valerio Setti43363f52022-12-14 08:53:23 +01001109}
Valerio Setti898e7a32022-12-14 08:55:53 +01001110#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001111
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001112#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001115
Valerio Setti43363f52022-12-14 08:53:23 +01001116#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */