blob: 67acfee481ce15da071dacae29763c30fbadc89a [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
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
Jens Wiklander32b31802023-10-06 16:59:46 +020025#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
26 defined(__clang__) && __clang_major__ >= 7
27/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
28 *
29 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
30 * these are normally only enabled by the -march option on the command line.
31 * By defining the macros ourselves we gain access to those declarations without
32 * requiring -march on the command line.
33 *
34 * `arm_neon.h` could be included by any header file, so we put these defines
35 * at the top of this file, before any includes.
36 */
37#define __ARM_FEATURE_SHA512 1
38#define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG
39#endif
40
Jerome Forissier79013242021-07-28 10:24:04 +020041#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020042
Jens Wiklander32b31802023-10-06 16:59:46 +020043#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Jens Wiklander817466c2018-05-22 13:49:31 +020044
45#include "mbedtls/sha512.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010046#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020047#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020048
49#if defined(_MSC_VER) || defined(__WATCOMC__)
50 #define UL64(x) x##ui64
51#else
52 #define UL64(x) x##ULL
53#endif
54
55#include <string.h>
56
Jens Wiklander817466c2018-05-22 13:49:31 +020057#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020058
Jens Wiklander32b31802023-10-06 16:59:46 +020059#if defined(__aarch64__)
60# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
61 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
62/* *INDENT-OFF* */
63/*
64 * Best performance comes from most recent compilers, with intrinsics and -O3.
65 * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
66 * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
67 *
68 * GCC < 8 won't work at all (lacks the sha512 instructions)
69 * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
70 *
71 * Clang < 7 won't work at all (lacks the sha512 instructions)
72 * Clang 7-12 don't have intrinsics (but we work around that with inline
73 * assembler) or __ARM_FEATURE_SHA512
74 * Clang == 13.0.0 same as clang 12 (only seen on macOS)
75 * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
76 */
77# if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG)
78 /* Test Clang first, as it defines __GNUC__ */
79# if defined(__clang__)
80# if __clang_major__ < 7
81# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
82# else
83# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
84# define MBEDTLS_POP_TARGET_PRAGMA
85# endif
86# elif defined(__GNUC__)
87# if __GNUC__ < 8
88# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
89# else
90# pragma GCC push_options
91# pragma GCC target ("arch=armv8.2-a+sha3")
92# define MBEDTLS_POP_TARGET_PRAGMA
93# endif
94# else
95# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
96# endif
97# endif
98/* *INDENT-ON* */
99# include <arm_neon.h>
100# endif
101# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
102# if defined(__unix__)
103# if defined(__linux__)
104/* Our preferred method of detection is getauxval() */
105# include <sys/auxv.h>
106# endif
107/* Use SIGILL on Unix, and fall back to it on Linux */
108# include <signal.h>
109# endif
110# endif
111#elif defined(_M_ARM64)
112# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
113 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
114# include <arm64_neon.h>
115# endif
116#else
117# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
118# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
119#endif
120
121#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
122/*
123 * Capability detection code comes early, so we can disable
124 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
125 */
126#if defined(HWCAP_SHA512)
127static int mbedtls_a64_crypto_sha512_determine_support(void)
128{
129 return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0;
130}
131#elif defined(__APPLE__)
132#include <sys/types.h>
133#include <sys/sysctl.h>
134
135static int mbedtls_a64_crypto_sha512_determine_support(void)
136{
137 int value = 0;
138 size_t value_len = sizeof(value);
139
140 int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len,
141 NULL, 0);
142 return ret == 0 && value != 0;
143}
144#elif defined(_M_ARM64)
145/*
146 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
147 * available to pass to IsProcessorFeaturePresent() to check for
148 * SHA-512 support. So we fall back to the C code only.
149 */
150#if defined(_MSC_VER)
151#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
152#else
153#warning "No mechanism to detect A64_CRYPTO found, using C code only"
154#endif
155#elif defined(__unix__) && defined(SIG_SETMASK)
156/* Detection with SIGILL, setjmp() and longjmp() */
157#include <signal.h>
158#include <setjmp.h>
159
160static jmp_buf return_from_sigill;
161
162/*
163 * A64 SHA512 support detection via SIGILL
164 */
165static void sigill_handler(int signal)
166{
167 (void) signal;
168 longjmp(return_from_sigill, 1);
169}
170
171static int mbedtls_a64_crypto_sha512_determine_support(void)
172{
173 struct sigaction old_action, new_action;
174
175 sigset_t old_mask;
176 if (sigprocmask(0, NULL, &old_mask)) {
177 return 0;
178 }
179
180 sigemptyset(&new_action.sa_mask);
181 new_action.sa_flags = 0;
182 new_action.sa_handler = sigill_handler;
183
184 sigaction(SIGILL, &new_action, &old_action);
185
186 static int ret = 0;
187
188 if (setjmp(return_from_sigill) == 0) { /* First return only */
189 /* If this traps, we will return a second time from setjmp() with 1 */
190 asm ("sha512h q0, q0, v0.2d" : : : "v0");
191 ret = 1;
192 }
193
194 sigaction(SIGILL, &old_action, NULL);
195 sigprocmask(SIG_SETMASK, &old_mask, NULL);
196
197 return ret;
198}
199#else
200#warning "No mechanism to detect A64_CRYPTO found, using C code only"
201#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
202#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
203
204#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Jens Wiklander817466c2018-05-22 13:49:31 +0200205
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100206#if !defined(MBEDTLS_SHA512_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +0200207
Jens Wiklander32b31802023-10-06 16:59:46 +0200208#define SHA512_BLOCK_SIZE 128
209
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200210#if defined(MBEDTLS_SHA512_SMALLER)
Jens Wiklander32b31802023-10-06 16:59:46 +0200211static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200212{
Jerome Forissier039e02d2022-08-09 17:10:15 +0200213 MBEDTLS_PUT_UINT64_BE(n, b, i);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200214}
215#else
Jerome Forissier039e02d2022-08-09 17:10:15 +0200216#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200217#endif /* MBEDTLS_SHA512_SMALLER */
218
Jens Wiklander32b31802023-10-06 16:59:46 +0200219void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200220{
Jens Wiklander32b31802023-10-06 16:59:46 +0200221 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200222}
223
Jens Wiklander32b31802023-10-06 16:59:46 +0200224void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200225{
Jens Wiklander32b31802023-10-06 16:59:46 +0200226 if (ctx == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200227 return;
Jens Wiklander32b31802023-10-06 16:59:46 +0200228 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200229
Jens Wiklander32b31802023-10-06 16:59:46 +0200230 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200231}
232
Jens Wiklander32b31802023-10-06 16:59:46 +0200233void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
234 const mbedtls_sha512_context *src)
Jens Wiklander817466c2018-05-22 13:49:31 +0200235{
236 *dst = *src;
237}
238
239/*
240 * SHA-512 context setup
241 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200242int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200243{
Jens Wiklander32b31802023-10-06 16:59:46 +0200244#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
245 if (is384 != 0 && is384 != 1) {
246 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
247 }
248#elif defined(MBEDTLS_SHA512_C)
249 if (is384 != 0) {
250 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
251 }
252#else /* defined MBEDTLS_SHA384_C only */
253 if (is384 == 0) {
254 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
255 }
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200256#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100257
Jens Wiklander817466c2018-05-22 13:49:31 +0200258 ctx->total[0] = 0;
259 ctx->total[1] = 0;
260
Jens Wiklander32b31802023-10-06 16:59:46 +0200261 if (is384 == 0) {
262#if defined(MBEDTLS_SHA512_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200263 ctx->state[0] = UL64(0x6A09E667F3BCC908);
264 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
265 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
266 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
267 ctx->state[4] = UL64(0x510E527FADE682D1);
268 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
269 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
270 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Jens Wiklander32b31802023-10-06 16:59:46 +0200271#endif /* MBEDTLS_SHA512_C */
272 } else {
273#if defined(MBEDTLS_SHA384_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200274 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
275 ctx->state[1] = UL64(0x629A292A367CD507);
276 ctx->state[2] = UL64(0x9159015A3070DD17);
277 ctx->state[3] = UL64(0x152FECD8F70E5939);
278 ctx->state[4] = UL64(0x67332667FFC00B31);
279 ctx->state[5] = UL64(0x8EB44A8768581511);
280 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
281 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Jens Wiklander32b31802023-10-06 16:59:46 +0200282#endif /* MBEDTLS_SHA384_C */
Jens Wiklander817466c2018-05-22 13:49:31 +0200283 }
284
Jens Wiklander32b31802023-10-06 16:59:46 +0200285#if defined(MBEDTLS_SHA384_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200286 ctx->is384 = is384;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200287#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100288
Jens Wiklander32b31802023-10-06 16:59:46 +0200289 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200290}
291
292#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
293
294/*
295 * Round constants
296 */
297static const uint64_t K[80] =
298{
299 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
300 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
301 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
302 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
303 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
304 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
305 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
306 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
307 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
308 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
309 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
310 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
311 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
312 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
313 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
314 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
315 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
316 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
317 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
318 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
319 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
320 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
321 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
322 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
323 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
324 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
325 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
326 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
327 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
328 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
329 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
330 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
331 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
332 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
333 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
334 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
335 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
336 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
337 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
338 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
339};
Jens Wiklander32b31802023-10-06 16:59:46 +0200340#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200341
Jens Wiklander32b31802023-10-06 16:59:46 +0200342#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
343 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
344
345#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
346# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
347# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
348#endif
349
350/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
351 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
352 */
353
354#if defined(__clang__) && \
355 (__clang_major__ < 13 || \
356 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
357static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
358{
359 asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y));
360 return x;
361}
362static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
363{
364 asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z));
365 return x;
366}
367static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
368{
369 asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
370 return x;
371}
372static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
373{
374 asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z));
375 return x;
376}
377#endif /* __clang__ etc */
378
379static size_t mbedtls_internal_sha512_process_many_a64_crypto(
380 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len)
381{
382 uint64x2_t ab = vld1q_u64(&ctx->state[0]);
383 uint64x2_t cd = vld1q_u64(&ctx->state[2]);
384 uint64x2_t ef = vld1q_u64(&ctx->state[4]);
385 uint64x2_t gh = vld1q_u64(&ctx->state[6]);
386
387 size_t processed = 0;
388
389 for (;
390 len >= SHA512_BLOCK_SIZE;
391 processed += SHA512_BLOCK_SIZE,
392 msg += SHA512_BLOCK_SIZE,
393 len -= SHA512_BLOCK_SIZE) {
394 uint64x2_t initial_sum, sum, intermed;
395
396 uint64x2_t ab_orig = ab;
397 uint64x2_t cd_orig = cd;
398 uint64x2_t ef_orig = ef;
399 uint64x2_t gh_orig = gh;
400
401 uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0);
402 uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1);
403 uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2);
404 uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3);
405 uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4);
406 uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5);
407 uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6);
408 uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7);
409
410#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
411 s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0)));
412 s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1)));
413 s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2)));
414 s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3)));
415 s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4)));
416 s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5)));
417 s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6)));
418 s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7)));
419#endif
420
421 /* Rounds 0 and 1 */
422 initial_sum = vaddq_u64(s0, vld1q_u64(&K[0]));
423 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
424 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
425 gh = vsha512h2q_u64(intermed, cd, ab);
426 cd = vaddq_u64(cd, intermed);
427
428 /* Rounds 2 and 3 */
429 initial_sum = vaddq_u64(s1, vld1q_u64(&K[2]));
430 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
431 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
432 ef = vsha512h2q_u64(intermed, ab, gh);
433 ab = vaddq_u64(ab, intermed);
434
435 /* Rounds 4 and 5 */
436 initial_sum = vaddq_u64(s2, vld1q_u64(&K[4]));
437 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
438 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
439 cd = vsha512h2q_u64(intermed, gh, ef);
440 gh = vaddq_u64(gh, intermed);
441
442 /* Rounds 6 and 7 */
443 initial_sum = vaddq_u64(s3, vld1q_u64(&K[6]));
444 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
445 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
446 ab = vsha512h2q_u64(intermed, ef, cd);
447 ef = vaddq_u64(ef, intermed);
448
449 /* Rounds 8 and 9 */
450 initial_sum = vaddq_u64(s4, vld1q_u64(&K[8]));
451 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
452 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
453 gh = vsha512h2q_u64(intermed, cd, ab);
454 cd = vaddq_u64(cd, intermed);
455
456 /* Rounds 10 and 11 */
457 initial_sum = vaddq_u64(s5, vld1q_u64(&K[10]));
458 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
459 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
460 ef = vsha512h2q_u64(intermed, ab, gh);
461 ab = vaddq_u64(ab, intermed);
462
463 /* Rounds 12 and 13 */
464 initial_sum = vaddq_u64(s6, vld1q_u64(&K[12]));
465 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
466 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
467 cd = vsha512h2q_u64(intermed, gh, ef);
468 gh = vaddq_u64(gh, intermed);
469
470 /* Rounds 14 and 15 */
471 initial_sum = vaddq_u64(s7, vld1q_u64(&K[14]));
472 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
473 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
474 ab = vsha512h2q_u64(intermed, ef, cd);
475 ef = vaddq_u64(ef, intermed);
476
477 for (unsigned int t = 16; t < 80; t += 16) {
478 /* Rounds t and t + 1 */
479 s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1));
480 initial_sum = vaddq_u64(s0, vld1q_u64(&K[t]));
481 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
482 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
483 gh = vsha512h2q_u64(intermed, cd, ab);
484 cd = vaddq_u64(cd, intermed);
485
486 /* Rounds t + 2 and t + 3 */
487 s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1));
488 initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2]));
489 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
490 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
491 ef = vsha512h2q_u64(intermed, ab, gh);
492 ab = vaddq_u64(ab, intermed);
493
494 /* Rounds t + 4 and t + 5 */
495 s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1));
496 initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4]));
497 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
498 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
499 cd = vsha512h2q_u64(intermed, gh, ef);
500 gh = vaddq_u64(gh, intermed);
501
502 /* Rounds t + 6 and t + 7 */
503 s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1));
504 initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6]));
505 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
506 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
507 ab = vsha512h2q_u64(intermed, ef, cd);
508 ef = vaddq_u64(ef, intermed);
509
510 /* Rounds t + 8 and t + 9 */
511 s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1));
512 initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8]));
513 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh);
514 intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1));
515 gh = vsha512h2q_u64(intermed, cd, ab);
516 cd = vaddq_u64(cd, intermed);
517
518 /* Rounds t + 10 and t + 11 */
519 s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1));
520 initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10]));
521 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef);
522 intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1));
523 ef = vsha512h2q_u64(intermed, ab, gh);
524 ab = vaddq_u64(ab, intermed);
525
526 /* Rounds t + 12 and t + 13 */
527 s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1));
528 initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12]));
529 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd);
530 intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1));
531 cd = vsha512h2q_u64(intermed, gh, ef);
532 gh = vaddq_u64(gh, intermed);
533
534 /* Rounds t + 14 and t + 15 */
535 s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1));
536 initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14]));
537 sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab);
538 intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1));
539 ab = vsha512h2q_u64(intermed, ef, cd);
540 ef = vaddq_u64(ef, intermed);
541 }
542
543 ab = vaddq_u64(ab, ab_orig);
544 cd = vaddq_u64(cd, cd_orig);
545 ef = vaddq_u64(ef, ef_orig);
546 gh = vaddq_u64(gh, gh_orig);
547 }
548
549 vst1q_u64(&ctx->state[0], ab);
550 vst1q_u64(&ctx->state[2], cd);
551 vst1q_u64(&ctx->state[4], ef);
552 vst1q_u64(&ctx->state[6], gh);
553
554 return processed;
555}
556
557#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
558/*
559 * This function is for internal use only if we are building both C and A64
560 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
561 */
562static
563#endif
564int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
565 const unsigned char data[SHA512_BLOCK_SIZE])
566{
567 return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data,
568 SHA512_BLOCK_SIZE) ==
569 SHA512_BLOCK_SIZE) ? 0 : -1;
570}
571
572#if defined(MBEDTLS_POP_TARGET_PRAGMA)
573#if defined(__clang__)
574#pragma clang attribute pop
575#elif defined(__GNUC__)
576#pragma GCC pop_options
577#endif
578#undef MBEDTLS_POP_TARGET_PRAGMA
579#endif
580
581#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
582
583
584#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
585#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
586#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
587#endif
588
589
590#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
591
592#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
593/*
594 * This function is for internal use only if we are building both C and A64
595 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
596 */
597static
598#endif
599int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx,
600 const unsigned char data[SHA512_BLOCK_SIZE])
Jens Wiklander817466c2018-05-22 13:49:31 +0200601{
602 int i;
Jens Wiklander32b31802023-10-06 16:59:46 +0200603 struct {
Jerome Forissier79013242021-07-28 10:24:04 +0200604 uint64_t temp1, temp2, W[80];
605 uint64_t A[8];
606 } local;
Jens Wiklander817466c2018-05-22 13:49:31 +0200607
Jens Wiklander32b31802023-10-06 16:59:46 +0200608#define SHR(x, n) ((x) >> (n))
609#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200610
611#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
Jens Wiklander32b31802023-10-06 16:59:46 +0200612#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Jens Wiklander817466c2018-05-22 13:49:31 +0200613
Jens Wiklander32b31802023-10-06 16:59:46 +0200614#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
615#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Jens Wiklander817466c2018-05-22 13:49:31 +0200616
Jens Wiklander32b31802023-10-06 16:59:46 +0200617#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
618#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200619
Jens Wiklander32b31802023-10-06 16:59:46 +0200620#define P(a, b, c, d, e, f, g, h, x, K) \
Jerome Forissier79013242021-07-28 10:24:04 +0200621 do \
622 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200623 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
624 local.temp2 = S2(a) + F0((a), (b), (c)); \
Jerome Forissier79013242021-07-28 10:24:04 +0200625 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Jens Wiklander32b31802023-10-06 16:59:46 +0200626 } while (0)
Jens Wiklander817466c2018-05-22 13:49:31 +0200627
Jens Wiklander32b31802023-10-06 16:59:46 +0200628 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200629 local.A[i] = ctx->state[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200630 }
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200631
632#if defined(MBEDTLS_SHA512_SMALLER)
Jens Wiklander32b31802023-10-06 16:59:46 +0200633 for (i = 0; i < 80; i++) {
634 if (i < 16) {
635 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
636 } else {
Jerome Forissier79013242021-07-28 10:24:04 +0200637 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Jens Wiklander32b31802023-10-06 16:59:46 +0200638 S0(local.W[i - 15]) + local.W[i - 16];
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200639 }
640
Jens Wiklander32b31802023-10-06 16:59:46 +0200641 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
642 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200643
Jerome Forissier79013242021-07-28 10:24:04 +0200644 local.temp1 = local.A[7]; local.A[7] = local.A[6];
645 local.A[6] = local.A[5]; local.A[5] = local.A[4];
646 local.A[4] = local.A[3]; local.A[3] = local.A[2];
647 local.A[2] = local.A[1]; local.A[1] = local.A[0];
648 local.A[0] = local.temp1;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200649 }
650#else /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander32b31802023-10-06 16:59:46 +0200651 for (i = 0; i < 16; i++) {
652 local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200653 }
654
Jens Wiklander32b31802023-10-06 16:59:46 +0200655 for (; i < 80; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200656 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
Jens Wiklander32b31802023-10-06 16:59:46 +0200657 S0(local.W[i - 15]) + local.W[i - 16];
Jens Wiklander817466c2018-05-22 13:49:31 +0200658 }
659
Jens Wiklander817466c2018-05-22 13:49:31 +0200660 i = 0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200661 do {
662 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
663 local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++;
664 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
665 local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++;
666 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
667 local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++;
668 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
669 local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++;
670 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
671 local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++;
672 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
673 local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++;
674 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
675 local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++;
676 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
677 local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++;
678 } while (i < 80);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200679#endif /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander817466c2018-05-22 13:49:31 +0200680
Jens Wiklander32b31802023-10-06 16:59:46 +0200681 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200682 ctx->state[i] += local.A[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200683 }
Jerome Forissier79013242021-07-28 10:24:04 +0200684
685 /* Zeroise buffers and variables to clear sensitive data from memory. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200686 mbedtls_platform_zeroize(&local, sizeof(local));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100687
Jens Wiklander32b31802023-10-06 16:59:46 +0200688 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200689}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100690
Jens Wiklander32b31802023-10-06 16:59:46 +0200691#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
692
693
694#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
695
696static size_t mbedtls_internal_sha512_process_many_c(
697 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100698{
Jens Wiklander32b31802023-10-06 16:59:46 +0200699 size_t processed = 0;
700
701 while (len >= SHA512_BLOCK_SIZE) {
702 if (mbedtls_internal_sha512_process_c(ctx, data) != 0) {
703 return 0;
704 }
705
706 data += SHA512_BLOCK_SIZE;
707 len -= SHA512_BLOCK_SIZE;
708
709 processed += SHA512_BLOCK_SIZE;
710 }
711
712 return processed;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100713}
Jens Wiklander32b31802023-10-06 16:59:46 +0200714
715#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
716
717
718#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
719
720static int mbedtls_a64_crypto_sha512_has_support(void)
721{
722 static int done = 0;
723 static int supported = 0;
724
725 if (!done) {
726 supported = mbedtls_a64_crypto_sha512_determine_support();
727 done = 1;
728 }
729
730 return supported;
731}
732
733static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx,
734 const uint8_t *msg, size_t len)
735{
736 if (mbedtls_a64_crypto_sha512_has_support()) {
737 return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len);
738 } else {
739 return mbedtls_internal_sha512_process_many_c(ctx, msg, len);
740 }
741}
742
743int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
744 const unsigned char data[SHA512_BLOCK_SIZE])
745{
746 if (mbedtls_a64_crypto_sha512_has_support()) {
747 return mbedtls_internal_sha512_process_a64_crypto(ctx, data);
748 } else {
749 return mbedtls_internal_sha512_process_c(ctx, data);
750 }
751}
752
753#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Jens Wiklander817466c2018-05-22 13:49:31 +0200754
755/*
756 * SHA-512 process buffer
757 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200758int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
759 const unsigned char *input,
760 size_t ilen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200761{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200762 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200763 size_t fill;
764 unsigned int left;
765
Jens Wiklander32b31802023-10-06 16:59:46 +0200766 if (ilen == 0) {
767 return 0;
768 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200769
770 left = (unsigned int) (ctx->total[0] & 0x7F);
Jens Wiklander32b31802023-10-06 16:59:46 +0200771 fill = SHA512_BLOCK_SIZE - left;
Jens Wiklander817466c2018-05-22 13:49:31 +0200772
773 ctx->total[0] += (uint64_t) ilen;
774
Jens Wiklander32b31802023-10-06 16:59:46 +0200775 if (ctx->total[0] < (uint64_t) ilen) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200776 ctx->total[1]++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200777 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200778
Jens Wiklander32b31802023-10-06 16:59:46 +0200779 if (left && ilen >= fill) {
780 memcpy((void *) (ctx->buffer + left), input, fill);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100781
Jens Wiklander32b31802023-10-06 16:59:46 +0200782 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
783 return ret;
784 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100785
Jens Wiklander817466c2018-05-22 13:49:31 +0200786 input += fill;
787 ilen -= fill;
788 left = 0;
789 }
790
Jens Wiklander32b31802023-10-06 16:59:46 +0200791 while (ilen >= SHA512_BLOCK_SIZE) {
792 size_t processed =
793 mbedtls_internal_sha512_process_many(ctx, input, ilen);
794 if (processed < SHA512_BLOCK_SIZE) {
795 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
796 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100797
Jens Wiklander32b31802023-10-06 16:59:46 +0200798 input += processed;
799 ilen -= processed;
Jens Wiklander817466c2018-05-22 13:49:31 +0200800 }
801
Jens Wiklander32b31802023-10-06 16:59:46 +0200802 if (ilen > 0) {
803 memcpy((void *) (ctx->buffer + left), input, ilen);
804 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100805
Jens Wiklander32b31802023-10-06 16:59:46 +0200806 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200807}
808
Jens Wiklander817466c2018-05-22 13:49:31 +0200809/*
810 * SHA-512 final digest
811 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200812int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
813 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +0200814{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200815 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100816 unsigned used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200817 uint64_t high, low;
Jens Wiklander817466c2018-05-22 13:49:31 +0200818
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100819 /*
820 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
821 */
822 used = ctx->total[0] & 0x7F;
823
824 ctx->buffer[used++] = 0x80;
825
Jens Wiklander32b31802023-10-06 16:59:46 +0200826 if (used <= 112) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100827 /* Enough room for padding + length in current block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200828 memset(ctx->buffer + used, 0, 112 - used);
829 } else {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100830 /* We'll need an extra block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200831 memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100832
Jens Wiklander32b31802023-10-06 16:59:46 +0200833 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
834 return ret;
835 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100836
Jens Wiklander32b31802023-10-06 16:59:46 +0200837 memset(ctx->buffer, 0, 112);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100838 }
839
840 /*
841 * Add message length
842 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200843 high = (ctx->total[0] >> 61)
844 | (ctx->total[1] << 3);
845 low = (ctx->total[0] << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200846
Jens Wiklander32b31802023-10-06 16:59:46 +0200847 sha512_put_uint64_be(high, ctx->buffer, 112);
848 sha512_put_uint64_be(low, ctx->buffer, 120);
Jens Wiklander817466c2018-05-22 13:49:31 +0200849
Jens Wiklander32b31802023-10-06 16:59:46 +0200850 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) {
851 return ret;
852 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200853
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100854 /*
855 * Output final state
856 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200857 sha512_put_uint64_be(ctx->state[0], output, 0);
858 sha512_put_uint64_be(ctx->state[1], output, 8);
859 sha512_put_uint64_be(ctx->state[2], output, 16);
860 sha512_put_uint64_be(ctx->state[3], output, 24);
861 sha512_put_uint64_be(ctx->state[4], output, 32);
862 sha512_put_uint64_be(ctx->state[5], output, 40);
Jens Wiklander817466c2018-05-22 13:49:31 +0200863
Jens Wiklander32b31802023-10-06 16:59:46 +0200864 int truncated = 0;
865#if defined(MBEDTLS_SHA384_C)
866 truncated = ctx->is384;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200867#endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200868 if (!truncated) {
869 sha512_put_uint64_be(ctx->state[6], output, 48);
870 sha512_put_uint64_be(ctx->state[7], output, 56);
Jens Wiklander817466c2018-05-22 13:49:31 +0200871 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100872
Jens Wiklander32b31802023-10-06 16:59:46 +0200873 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200874}
875
876#endif /* !MBEDTLS_SHA512_ALT */
877
878/*
879 * output = SHA-512( input buffer )
880 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200881int mbedtls_sha512(const unsigned char *input,
882 size_t ilen,
883 unsigned char *output,
884 int is384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200885{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200886 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200887 mbedtls_sha512_context ctx;
888
Jens Wiklander32b31802023-10-06 16:59:46 +0200889#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
890 if (is384 != 0 && is384 != 1) {
891 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
892 }
893#elif defined(MBEDTLS_SHA512_C)
894 if (is384 != 0) {
895 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
896 }
897#else /* defined MBEDTLS_SHA384_C only */
898 if (is384 == 0) {
899 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
900 }
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200901#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100902
Jens Wiklander32b31802023-10-06 16:59:46 +0200903 mbedtls_sha512_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100904
Jens Wiklander32b31802023-10-06 16:59:46 +0200905 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100906 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200907 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100908
Jens Wiklander32b31802023-10-06 16:59:46 +0200909 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100910 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200911 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100912
Jens Wiklander32b31802023-10-06 16:59:46 +0200913 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100914 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200915 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100916
917exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200918 mbedtls_sha512_free(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100919
Jens Wiklander32b31802023-10-06 16:59:46 +0200920 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200921}
922
923#if defined(MBEDTLS_SELF_TEST)
924
925/*
926 * FIPS-180-2 test vectors
927 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200928static const unsigned char sha_test_buf[3][113] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200929{
930 { "abc" },
Jens Wiklander32b31802023-10-06 16:59:46 +0200931 {
932 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
933 },
Jens Wiklander817466c2018-05-22 13:49:31 +0200934 { "" }
935};
936
Jens Wiklander32b31802023-10-06 16:59:46 +0200937static const size_t sha_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200938{
939 3, 112, 1000
940};
941
Jens Wiklander32b31802023-10-06 16:59:46 +0200942typedef const unsigned char (sha_test_sum_t)[64];
943
944/*
945 * SHA-384 test vectors
946 */
947#if defined(MBEDTLS_SHA384_C)
948static sha_test_sum_t sha384_test_sum[] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200949{
Jens Wiklander817466c2018-05-22 13:49:31 +0200950 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
951 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
952 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
953 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
954 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
955 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
956 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
957 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
958 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
959 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
960 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
961 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
962 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
963 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
964 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
965 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
966 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Jens Wiklander32b31802023-10-06 16:59:46 +0200967 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
968};
969#endif /* MBEDTLS_SHA384_C */
Jens Wiklander817466c2018-05-22 13:49:31 +0200970
Jens Wiklander32b31802023-10-06 16:59:46 +0200971/*
972 * SHA-512 test vectors
973 */
974#if defined(MBEDTLS_SHA512_C)
975static sha_test_sum_t sha512_test_sum[] =
976{
Jens Wiklander817466c2018-05-22 13:49:31 +0200977 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
978 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
979 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
980 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
981 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
982 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
983 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
984 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
985 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
986 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
987 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
988 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
989 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
990 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
991 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
992 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
993 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
994 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
995 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
996 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
997 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
998 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
999 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
1000 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
1001};
Jens Wiklander32b31802023-10-06 16:59:46 +02001002#endif /* MBEDTLS_SHA512_C */
Jens Wiklander817466c2018-05-22 13:49:31 +02001003
Jens Wiklander32b31802023-10-06 16:59:46 +02001004#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001005
Jens Wiklander32b31802023-10-06 16:59:46 +02001006static int mbedtls_sha512_common_self_test(int verbose, int is384)
Jens Wiklander817466c2018-05-22 13:49:31 +02001007{
Jens Wiklander32b31802023-10-06 16:59:46 +02001008 int i, buflen, ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02001009 unsigned char *buf;
1010 unsigned char sha512sum[64];
1011 mbedtls_sha512_context ctx;
1012
Jens Wiklander32b31802023-10-06 16:59:46 +02001013#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
1014 sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum;
1015#elif defined(MBEDTLS_SHA512_C)
1016 sha_test_sum_t *sha_test_sum = sha512_test_sum;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001017#else
Jens Wiklander32b31802023-10-06 16:59:46 +02001018 sha_test_sum_t *sha_test_sum = sha384_test_sum;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001019#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001020
Jens Wiklander32b31802023-10-06 16:59:46 +02001021 buf = mbedtls_calloc(1024, sizeof(unsigned char));
1022 if (NULL == buf) {
1023 if (verbose != 0) {
1024 mbedtls_printf("Buffer allocation failed\n");
1025 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001026
Jens Wiklander32b31802023-10-06 16:59:46 +02001027 return 1;
1028 }
1029
1030 mbedtls_sha512_init(&ctx);
1031
1032 for (i = 0; i < 3; i++) {
1033 if (verbose != 0) {
1034 mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1);
1035 }
1036
1037 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001038 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +02001039 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001040
Jens Wiklander32b31802023-10-06 16:59:46 +02001041 if (i == 2) {
1042 memset(buf, 'a', buflen = 1000);
Jens Wiklander817466c2018-05-22 13:49:31 +02001043
Jens Wiklander32b31802023-10-06 16:59:46 +02001044 for (int j = 0; j < 1000; j++) {
1045 ret = mbedtls_sha512_update(&ctx, buf, buflen);
1046 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001047 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +02001048 }
1049 }
1050 } else {
1051 ret = mbedtls_sha512_update(&ctx, sha_test_buf[i],
1052 sha_test_buflen[i]);
1053 if (ret != 0) {
1054 goto fail;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001055 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001056 }
Jens Wiklander32b31802023-10-06 16:59:46 +02001057
1058 if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) {
1059 goto fail;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001060 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001061
Jens Wiklander32b31802023-10-06 16:59:46 +02001062 if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001063 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001064 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +02001065 }
1066
Jens Wiklander32b31802023-10-06 16:59:46 +02001067 if (verbose != 0) {
1068 mbedtls_printf("passed\n");
1069 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001070 }
1071
Jens Wiklander32b31802023-10-06 16:59:46 +02001072 if (verbose != 0) {
1073 mbedtls_printf("\n");
1074 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001075
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001076 goto exit;
1077
1078fail:
Jens Wiklander32b31802023-10-06 16:59:46 +02001079 if (verbose != 0) {
1080 mbedtls_printf("failed\n");
1081 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001082
Jens Wiklander817466c2018-05-22 13:49:31 +02001083exit:
Jens Wiklander32b31802023-10-06 16:59:46 +02001084 mbedtls_sha512_free(&ctx);
1085 mbedtls_free(buf);
Jens Wiklander817466c2018-05-22 13:49:31 +02001086
Jens Wiklander32b31802023-10-06 16:59:46 +02001087 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02001088}
1089
Jens Wiklander32b31802023-10-06 16:59:46 +02001090#if defined(MBEDTLS_SHA512_C)
1091int mbedtls_sha512_self_test(int verbose)
1092{
1093 return mbedtls_sha512_common_self_test(verbose, 0);
1094}
1095#endif /* MBEDTLS_SHA512_C */
1096
1097#if defined(MBEDTLS_SHA384_C)
1098int mbedtls_sha384_self_test(int verbose)
1099{
1100 return mbedtls_sha512_common_self_test(verbose, 1);
1101}
1102#endif /* MBEDTLS_SHA384_C */
1103
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001104#undef ARRAY_LENGTH
1105
Jens Wiklander817466c2018-05-22 13:49:31 +02001106#endif /* MBEDTLS_SELF_TEST */
1107
Jens Wiklander32b31802023-10-06 16:59:46 +02001108#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */