blob: 46e3dabb1e242e7be7817c4e0ca0bd4ed1b6a363 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Valerio Setti43363f52022-12-14 08:53:23 +010027#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000033#if defined(_MSC_VER) || defined(__WATCOMC__)
34 #define UL64(x) x##ui64
35#else
36 #define UL64(x) x##ULL
37#endif
38
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010042
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000043#if defined(__aarch64__)
44# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
45 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
46# include <arm_neon.h>
47# endif
48# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
49# if defined(__unix__)
50# if defined(__linux__)
51 /* Our preferred method of detection is getauxval() */
52# include <sys/auxv.h>
53# endif
54 /* Use SIGILL on Unix, and fall back to it on Linux */
55# include <signal.h>
56# endif
57# endif
58#elif defined(_M_ARM64)
59# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
60 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
61# include <arm64_neon.h>
62# endif
63#else
64# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
65# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
66#endif
67
68#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
69/*
70 * Capability detection code comes early, so we can disable
71 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
72 */
73#if defined(HWCAP_SHA512)
74static int mbedtls_a64_crypto_sha512_determine_support( void )
75{
76 return( ( getauxval( AT_HWCAP ) & HWCAP_SHA512 ) ? 1 : 0 );
77}
78#elif defined(__APPLE__)
79#include <sys/types.h>
80#include <sys/sysctl.h>
81
82static int mbedtls_a64_crypto_sha512_determine_support( void )
83{
84 int value = 0;
85 size_t value_len = sizeof(value);
86
87 int ret = sysctlbyname( "hw.optional.armv8_2_sha512", &value, &value_len,
88 NULL, 0 );
89 return( ret == 0 && value != 0 );
90}
91#elif defined(_M_ARM64)
92/*
93 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
94 * available to pass to IsProcessorFeaturePresent() to check for
95 * SHA-512 support. So we fall back to the C code only.
96 */
97#if defined(_MSC_VER)
98#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
99#else
100#warning "No mechanism to detect A64_CRYPTO found, using C code only"
101#endif
102#elif defined(__unix__) && defined(SIG_SETMASK)
103/* Detection with SIGILL, setjmp() and longjmp() */
104#include <signal.h>
105#include <setjmp.h>
106
David Horstmanne3d8f312023-01-03 11:07:09 +0000107/* *INDENT-OFF* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000108#ifndef asm
109#define asm __asm__
110#endif
David Horstmanne3d8f312023-01-03 11:07:09 +0000111/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000112
113static jmp_buf return_from_sigill;
114
115/*
116 * A64 SHA512 support detection via SIGILL
117 */
118static void sigill_handler( int signal )
119{
120 (void) signal;
121 longjmp( return_from_sigill, 1 );
122}
123
124static int mbedtls_a64_crypto_sha512_determine_support( void )
125{
126 struct sigaction old_action, new_action;
127
128 sigset_t old_mask;
129 if( sigprocmask( 0, NULL, &old_mask ) )
130 return( 0 );
131
132 sigemptyset( &new_action.sa_mask );
133 new_action.sa_flags = 0;
134 new_action.sa_handler = sigill_handler;
135
136 sigaction( SIGILL, &new_action, &old_action );
137
138 static int ret = 0;
139
140 if( setjmp( return_from_sigill ) == 0 ) /* First return only */
141 {
142 /* If this traps, we will return a second time from setjmp() with 1 */
143 asm( "sha512h q0, q0, v0.2d" : : : "v0" );
144 ret = 1;
145 }
146
147 sigaction( SIGILL, &old_action, NULL );
148 sigprocmask( SIG_SETMASK, &old_mask, NULL );
149
150 return( ret );
151}
152#else
153#warning "No mechanism to detect A64_CRYPTO found, using C code only"
154#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
155#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
156
157#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
158
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200159#if !defined(MBEDTLS_SHA512_ALT)
160
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000161#define SHA512_BLOCK_SIZE 128
162
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200163#if defined(MBEDTLS_SHA512_SMALLER)
164static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
165{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100166 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200167}
168#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100169#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200170#endif /* MBEDTLS_SHA512_SMALLER */
171
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200173{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200174 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200175}
176
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200178{
179 if( ctx == NULL )
180 return;
181
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500182 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200183}
184
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200185void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
186 const mbedtls_sha512_context *src )
187{
188 *dst = *src;
189}
190
Paul Bakker5121ce52009-01-03 21:22:43 +0000191/*
192 * SHA-512 context setup
193 */
TRodziewicz26371e42021-06-08 16:45:41 +0200194int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000195{
Valerio Setti43363f52022-12-14 08:53:23 +0100196#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100197 if( is384 != 0 && is384 != 1 )
198 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Valerio Setti43363f52022-12-14 08:53:23 +0100199#elif defined(MBEDTLS_SHA512_C)
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100200 if( is384 != 0 )
201 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Valerio Setti43363f52022-12-14 08:53:23 +0100202#else /* defined MBEDTLS_SHA384_C only */
203 if( is384 == 0 )
204 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100205#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000206
Paul Bakker5121ce52009-01-03 21:22:43 +0000207 ctx->total[0] = 0;
208 ctx->total[1] = 0;
209
210 if( is384 == 0 )
211 {
Valerio Setti43363f52022-12-14 08:53:23 +0100212#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000213 ctx->state[0] = UL64(0x6A09E667F3BCC908);
214 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
215 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
216 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
217 ctx->state[4] = UL64(0x510E527FADE682D1);
218 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
219 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
220 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100221#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000222 }
223 else
224 {
Valerio Setti43363f52022-12-14 08:53:23 +0100225#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000226 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
227 ctx->state[1] = UL64(0x629A292A367CD507);
228 ctx->state[2] = UL64(0x9159015A3070DD17);
229 ctx->state[3] = UL64(0x152FECD8F70E5939);
230 ctx->state[4] = UL64(0x67332667FFC00B31);
231 ctx->state[5] = UL64(0x8EB44A8768581511);
232 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
233 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200234#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000235 }
236
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200237#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000238 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200239#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100240
241 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000242}
243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200245
246/*
247 * Round constants
248 */
249static const uint64_t K[80] =
250{
251 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
252 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
253 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
254 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
255 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
256 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
257 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
258 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
259 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
260 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
261 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
262 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
263 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
264 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
265 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
266 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
267 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
268 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
269 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
270 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
271 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
272 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
273 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
274 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
275 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
276 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
277 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
278 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
279 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
280 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
281 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
282 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
283 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
284 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
285 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
286 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
287 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
288 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
289 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
290 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
291};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000292#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200293
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000294#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
295 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
296
297#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
298# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
299# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
300#endif
301
David Horstmanne3d8f312023-01-03 11:07:09 +0000302/* *INDENT-OFF* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000303#ifndef asm
304#define asm __asm__
305#endif
David Horstmanne3d8f312023-01-03 11:07:09 +0000306/* *INDENT-ON* */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000307
308/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
309 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
310 */
311
312#if defined(__clang__) && \
313 (__clang_major__ < 13 || \
314 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
315static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
316{
317 asm( "sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y) );
318 return( x );
319}
320static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
321{
322 asm( "sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
323 return( x );
324}
325static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
326{
327 asm( "sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
328 return( x );
329}
330static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
331{
332 asm( "sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
333 return( x );
334}
335#endif /* __clang__ etc */
336
337static size_t mbedtls_internal_sha512_process_many_a64_crypto(
338 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len )
339{
340 uint64x2_t ab = vld1q_u64( &ctx->state[0] );
341 uint64x2_t cd = vld1q_u64( &ctx->state[2] );
342 uint64x2_t ef = vld1q_u64( &ctx->state[4] );
343 uint64x2_t gh = vld1q_u64( &ctx->state[6] );
344
345 size_t processed = 0;
346
347 for ( ;
348 len >= SHA512_BLOCK_SIZE;
349 processed += SHA512_BLOCK_SIZE,
350 msg += SHA512_BLOCK_SIZE,
351 len -= SHA512_BLOCK_SIZE )
352 {
353 uint64x2_t initial_sum, sum, intermed;
354
355 uint64x2_t ab_orig = ab;
356 uint64x2_t cd_orig = cd;
357 uint64x2_t ef_orig = ef;
358 uint64x2_t gh_orig = gh;
359
360 uint64x2_t s0 = (uint64x2_t) vld1q_u8( msg + 16 * 0 );
361 uint64x2_t s1 = (uint64x2_t) vld1q_u8( msg + 16 * 1 );
362 uint64x2_t s2 = (uint64x2_t) vld1q_u8( msg + 16 * 2 );
363 uint64x2_t s3 = (uint64x2_t) vld1q_u8( msg + 16 * 3 );
364 uint64x2_t s4 = (uint64x2_t) vld1q_u8( msg + 16 * 4 );
365 uint64x2_t s5 = (uint64x2_t) vld1q_u8( msg + 16 * 5 );
366 uint64x2_t s6 = (uint64x2_t) vld1q_u8( msg + 16 * 6 );
367 uint64x2_t s7 = (uint64x2_t) vld1q_u8( msg + 16 * 7 );
368
369#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
370 s0 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s0 ) ) );
371 s1 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s1 ) ) );
372 s2 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s2 ) ) );
373 s3 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s3 ) ) );
374 s4 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s4 ) ) );
375 s5 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s5 ) ) );
376 s6 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s6 ) ) );
377 s7 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s7 ) ) );
378#endif
379
380 /* Rounds 0 and 1 */
381 initial_sum = vaddq_u64( s0, vld1q_u64( &K[0] ) );
382 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
383 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
384 gh = vsha512h2q_u64( intermed, cd, ab );
385 cd = vaddq_u64( cd, intermed );
386
387 /* Rounds 2 and 3 */
388 initial_sum = vaddq_u64( s1, vld1q_u64( &K[2] ) );
389 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
390 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
391 ef = vsha512h2q_u64( intermed, ab, gh );
392 ab = vaddq_u64( ab, intermed );
393
394 /* Rounds 4 and 5 */
395 initial_sum = vaddq_u64( s2, vld1q_u64( &K[4] ) );
396 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
397 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
398 cd = vsha512h2q_u64( intermed, gh, ef );
399 gh = vaddq_u64( gh, intermed );
400
401 /* Rounds 6 and 7 */
402 initial_sum = vaddq_u64( s3, vld1q_u64( &K[6] ) );
403 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
404 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
405 ab = vsha512h2q_u64( intermed, ef, cd );
406 ef = vaddq_u64( ef, intermed );
407
408 /* Rounds 8 and 9 */
409 initial_sum = vaddq_u64( s4, vld1q_u64( &K[8] ) );
410 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
411 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
412 gh = vsha512h2q_u64( intermed, cd, ab );
413 cd = vaddq_u64( cd, intermed );
414
415 /* Rounds 10 and 11 */
416 initial_sum = vaddq_u64( s5, vld1q_u64( &K[10] ) );
417 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
418 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
419 ef = vsha512h2q_u64( intermed, ab, gh );
420 ab = vaddq_u64( ab, intermed );
421
422 /* Rounds 12 and 13 */
423 initial_sum = vaddq_u64( s6, vld1q_u64( &K[12] ) );
424 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
425 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
426 cd = vsha512h2q_u64( intermed, gh, ef );
427 gh = vaddq_u64( gh, intermed );
428
429 /* Rounds 14 and 15 */
430 initial_sum = vaddq_u64( s7, vld1q_u64( &K[14] ) );
431 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
432 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
433 ab = vsha512h2q_u64( intermed, ef, cd );
434 ef = vaddq_u64( ef, intermed );
435
436 for ( unsigned int t = 16; t < 80; t += 16 )
437 {
438 /* Rounds t and t + 1 */
439 s0 = vsha512su1q_u64( vsha512su0q_u64( s0, s1 ), s7, vextq_u64( s4, s5, 1 ) );
440 initial_sum = vaddq_u64( s0, vld1q_u64( &K[t] ) );
441 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
442 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
443 gh = vsha512h2q_u64( intermed, cd, ab );
444 cd = vaddq_u64( cd, intermed );
445
446 /* Rounds t + 2 and t + 3 */
447 s1 = vsha512su1q_u64( vsha512su0q_u64( s1, s2 ), s0, vextq_u64( s5, s6, 1 ) );
448 initial_sum = vaddq_u64( s1, vld1q_u64( &K[t + 2] ) );
449 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
450 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
451 ef = vsha512h2q_u64( intermed, ab, gh );
452 ab = vaddq_u64( ab, intermed );
453
454 /* Rounds t + 4 and t + 5 */
455 s2 = vsha512su1q_u64( vsha512su0q_u64( s2, s3 ), s1, vextq_u64( s6, s7, 1 ) );
456 initial_sum = vaddq_u64( s2, vld1q_u64( &K[t + 4] ) );
457 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
458 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
459 cd = vsha512h2q_u64( intermed, gh, ef );
460 gh = vaddq_u64( gh, intermed );
461
462 /* Rounds t + 6 and t + 7 */
463 s3 = vsha512su1q_u64( vsha512su0q_u64( s3, s4 ), s2, vextq_u64( s7, s0, 1 ) );
464 initial_sum = vaddq_u64( s3, vld1q_u64( &K[t + 6] ) );
465 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
466 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
467 ab = vsha512h2q_u64( intermed, ef, cd );
468 ef = vaddq_u64( ef, intermed );
469
470 /* Rounds t + 8 and t + 9 */
471 s4 = vsha512su1q_u64( vsha512su0q_u64( s4, s5 ), s3, vextq_u64( s0, s1, 1 ) );
472 initial_sum = vaddq_u64( s4, vld1q_u64( &K[t + 8] ) );
473 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
474 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
475 gh = vsha512h2q_u64( intermed, cd, ab );
476 cd = vaddq_u64( cd, intermed );
477
478 /* Rounds t + 10 and t + 11 */
479 s5 = vsha512su1q_u64( vsha512su0q_u64( s5, s6 ), s4, vextq_u64( s1, s2, 1 ) );
480 initial_sum = vaddq_u64( s5, vld1q_u64( &K[t + 10] ) );
481 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
482 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
483 ef = vsha512h2q_u64( intermed, ab, gh );
484 ab = vaddq_u64( ab, intermed );
485
486 /* Rounds t + 12 and t + 13 */
487 s6 = vsha512su1q_u64( vsha512su0q_u64( s6, s7 ), s5, vextq_u64( s2, s3, 1 ) );
488 initial_sum = vaddq_u64( s6, vld1q_u64( &K[t + 12] ) );
489 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
490 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
491 cd = vsha512h2q_u64( intermed, gh, ef );
492 gh = vaddq_u64( gh, intermed );
493
494 /* Rounds t + 14 and t + 15 */
495 s7 = vsha512su1q_u64( vsha512su0q_u64( s7, s0 ), s6, vextq_u64( s3, s4, 1 ) );
496 initial_sum = vaddq_u64( s7, vld1q_u64( &K[t + 14] ) );
497 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
498 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
499 ab = vsha512h2q_u64( intermed, ef, cd );
500 ef = vaddq_u64( ef, intermed );
501 }
502
503 ab = vaddq_u64( ab, ab_orig );
504 cd = vaddq_u64( cd, cd_orig );
505 ef = vaddq_u64( ef, ef_orig );
506 gh = vaddq_u64( gh, gh_orig );
507 }
508
509 vst1q_u64( &ctx->state[0], ab );
510 vst1q_u64( &ctx->state[2], cd );
511 vst1q_u64( &ctx->state[4], ef );
512 vst1q_u64( &ctx->state[6], gh );
513
514 return( processed );
515}
516
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100517#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
518/*
519 * This function is for internal use only if we are building both C and A64
520 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
521 */
522static
523#endif
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000524int mbedtls_internal_sha512_process_a64_crypto( mbedtls_sha512_context *ctx,
525 const unsigned char data[SHA512_BLOCK_SIZE] )
526{
527 return( mbedtls_internal_sha512_process_many_a64_crypto( ctx, data,
528 SHA512_BLOCK_SIZE ) == SHA512_BLOCK_SIZE ) ? 0 : -1;
529}
530
531#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
532
533
534#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
535#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
536#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
537#endif
538
539
540#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
541
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100542#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
543/*
544 * This function is for internal use only if we are building both C and A64
545 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
546 */
547static
548#endif
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000549int mbedtls_internal_sha512_process_c( mbedtls_sha512_context *ctx,
550 const unsigned char data[SHA512_BLOCK_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000551{
552 int i;
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200553 struct
554 {
555 uint64_t temp1, temp2, W[80];
556 uint64_t A[8];
557 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
Hanno Becker1eeca412018-10-15 12:01:35 +0100559#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000560#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000561
562#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
563#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
564
565#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
566#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
567
Hanno Becker1eeca412018-10-15 12:01:35 +0100568#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
569#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200571#define P(a,b,c,d,e,f,g,h,x,K) \
572 do \
573 { \
574 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
575 local.temp2 = S2(a) + F0((a),(b),(c)); \
576 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100577 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000578
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200579 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200580 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200581
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200582#if defined(MBEDTLS_SHA512_SMALLER)
583 for( i = 0; i < 80; i++ )
584 {
585 if( i < 16 )
586 {
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100587 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200588 }
589 else
590 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200591 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
592 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200593 }
594
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200595 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
596 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200597
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200598 local.temp1 = local.A[7]; local.A[7] = local.A[6];
599 local.A[6] = local.A[5]; local.A[5] = local.A[4];
600 local.A[4] = local.A[3]; local.A[3] = local.A[2];
601 local.A[2] = local.A[1]; local.A[1] = local.A[0];
602 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200603 }
604#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000605 for( i = 0; i < 16; i++ )
606 {
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100607 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
609
610 for( ; i < 80; i++ )
611 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200612 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
613 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000614 }
615
Paul Bakker5121ce52009-01-03 21:22:43 +0000616 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000617 do
618 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200619 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
620 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
621 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
622 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
623 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
624 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
625 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
626 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
627 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
628 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
629 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
630 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
631 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
632 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
633 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
634 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 }
636 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200637#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200639 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200640 ctx->state[i] += local.A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100641
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200642 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200643 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100644
645 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000646}
Jaeden Amero041039f2018-02-19 15:28:08 +0000647
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000648#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
649
650
651#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
652
653static size_t mbedtls_internal_sha512_process_many_c(
654 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
655{
656 size_t processed = 0;
657
658 while( len >= SHA512_BLOCK_SIZE )
659 {
660 if( mbedtls_internal_sha512_process_c( ctx, data ) != 0)
661 return( 0 );
662
663 data += SHA512_BLOCK_SIZE;
664 len -= SHA512_BLOCK_SIZE;
665
666 processed += SHA512_BLOCK_SIZE;
667 }
668
669 return( processed );
670}
671
672#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
673
674
675#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
676
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100677static int mbedtls_a64_crypto_sha512_has_support( void )
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000678{
679 static int done = 0;
680 static int supported = 0;
681
682 if( !done )
683 {
684 supported = mbedtls_a64_crypto_sha512_determine_support();
685 done = 1;
686 }
687
688 return( supported );
689}
690
691static size_t mbedtls_internal_sha512_process_many( mbedtls_sha512_context *ctx,
692 const uint8_t *msg, size_t len )
693{
694 if( mbedtls_a64_crypto_sha512_has_support() )
695 return( mbedtls_internal_sha512_process_many_a64_crypto( ctx, msg, len ) );
696 else
697 return( mbedtls_internal_sha512_process_many_c( ctx, msg, len ) );
698}
699
700int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
701 const unsigned char data[SHA512_BLOCK_SIZE] )
702{
703 if( mbedtls_a64_crypto_sha512_has_support() )
704 return( mbedtls_internal_sha512_process_a64_crypto( ctx, data ) );
705 else
706 return( mbedtls_internal_sha512_process_c( ctx, data ) );
707}
708
709#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
711/*
712 * SHA-512 process buffer
713 */
TRodziewicz26371e42021-06-08 16:45:41 +0200714int mbedtls_sha512_update( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100715 const unsigned char *input,
716 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000717{
Janos Follath24eed8d2019-11-22 13:21:35 +0000718 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000719 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000720 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000721
Brian White12895d12014-04-11 11:29:42 -0400722 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100723 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
Paul Bakkerb8213a12011-07-11 08:16:18 +0000725 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000726 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
Paul Bakker5c2364c2012-10-01 14:41:15 +0000728 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000729
Paul Bakker5c2364c2012-10-01 14:41:15 +0000730 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000731 ctx->total[1]++;
732
733 if( left && ilen >= fill )
734 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200735 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100736
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100737 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100738 return( ret );
739
Paul Bakker5121ce52009-01-03 21:22:43 +0000740 input += fill;
741 ilen -= fill;
742 left = 0;
743 }
744
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000745 while( ilen >= SHA512_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000746 {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000747 size_t processed =
748 mbedtls_internal_sha512_process_many( ctx, input, ilen );
749 if( processed < SHA512_BLOCK_SIZE )
750 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100751
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000752 input += processed;
753 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000754 }
755
756 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200757 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100758
759 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000760}
761
Paul Bakker5121ce52009-01-03 21:22:43 +0000762/*
763 * SHA-512 final digest
764 */
TRodziewicz26371e42021-06-08 16:45:41 +0200765int mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
Gilles Peskinee02e02f2021-05-13 00:22:35 +0200766 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000767{
Janos Follath24eed8d2019-11-22 13:21:35 +0000768 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200769 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000770 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200772 /*
773 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
774 */
775 used = ctx->total[0] & 0x7F;
776
777 ctx->buffer[used++] = 0x80;
778
779 if( used <= 112 )
780 {
781 /* Enough room for padding + length in current block */
782 memset( ctx->buffer + used, 0, 112 - used );
783 }
784 else
785 {
786 /* We'll need an extra block */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000787 memset( ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200788
789 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
790 return( ret );
791
792 memset( ctx->buffer, 0, 112 );
793 }
794
795 /*
796 * Add message length
797 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000798 high = ( ctx->total[0] >> 61 )
799 | ( ctx->total[1] << 3 );
800 low = ( ctx->total[0] << 3 );
801
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200802 sha512_put_uint64_be( high, ctx->buffer, 112 );
803 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000804
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200805 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
806 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000807
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200808 /*
809 * Output final state
810 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200811 sha512_put_uint64_be( ctx->state[0], output, 0 );
812 sha512_put_uint64_be( ctx->state[1], output, 8 );
813 sha512_put_uint64_be( ctx->state[2], output, 16 );
814 sha512_put_uint64_be( ctx->state[3], output, 24 );
815 sha512_put_uint64_be( ctx->state[4], output, 32 );
816 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000817
David Horstmann2788f6b2022-10-06 18:45:09 +0100818 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200819#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100820 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200821#endif
David Horstmann2788f6b2022-10-06 18:45:09 +0100822 if( !truncated )
Paul Bakker5121ce52009-01-03 21:22:43 +0000823 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200824 sha512_put_uint64_be( ctx->state[6], output, 48 );
825 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000826 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100827
828 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000829}
830
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200831#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200832
Paul Bakker5121ce52009-01-03 21:22:43 +0000833/*
834 * output = SHA-512( input buffer )
835 */
TRodziewicz26371e42021-06-08 16:45:41 +0200836int mbedtls_sha512( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100837 size_t ilen,
Gilles Peskinee02e02f2021-05-13 00:22:35 +0200838 unsigned char *output,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100839 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000840{
Janos Follath24eed8d2019-11-22 13:21:35 +0000841 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000843
Valerio Setti43363f52022-12-14 08:53:23 +0100844#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100845 if( is384 != 0 && is384 != 1 )
846 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Valerio Setti43363f52022-12-14 08:53:23 +0100847#elif defined(MBEDTLS_SHA512_C)
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100848 if( is384 != 0 )
849 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Valerio Setti43363f52022-12-14 08:53:23 +0100850#else /* defined MBEDTLS_SHA384_C only */
851 if( is384 == 0 )
852 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100853#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000854
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100856
TRodziewicz26371e42021-06-08 16:45:41 +0200857 if( ( ret = mbedtls_sha512_starts( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100858 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100859
TRodziewicz26371e42021-06-08 16:45:41 +0200860 if( ( ret = mbedtls_sha512_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100861 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100862
TRodziewicz26371e42021-06-08 16:45:41 +0200863 if( ( ret = mbedtls_sha512_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100864 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100865
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100866exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100868
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100869 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000870}
871
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000873
874/*
875 * FIPS-180-2 test vectors
876 */
Valerio Setti43363f52022-12-14 08:53:23 +0100877static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000878{
879 { "abc" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200880 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000881 { "" }
882};
883
Valerio Setti43363f52022-12-14 08:53:23 +0100884static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000885{
886 3, 112, 1000
887};
888
Valerio Setti43363f52022-12-14 08:53:23 +0100889typedef const unsigned char (sha_test_sum_t)[64];
890
891/*
892 * SHA-384 test vectors
893 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200894#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100895static sha_test_sum_t sha384_test_sum[] =
896{
Paul Bakker5121ce52009-01-03 21:22:43 +0000897 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
898 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
899 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
900 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
901 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
902 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
903 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
904 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
905 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
906 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
907 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
908 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
909 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
910 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
911 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
912 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
913 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100914 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
915};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200916#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
Valerio Setti43363f52022-12-14 08:53:23 +0100918/*
919 * SHA-512 test vectors
920 */
921#if defined(MBEDTLS_SHA512_C)
922static sha_test_sum_t sha512_test_sum[] =
923{
Paul Bakker5121ce52009-01-03 21:22:43 +0000924 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
925 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
926 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
927 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
928 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
929 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
930 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
931 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
932 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
933 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
934 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
935 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
936 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
937 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
938 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
939 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
940 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
941 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
942 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
943 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
944 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
945 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
946 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
947 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
948};
Valerio Setti43363f52022-12-14 08:53:23 +0100949#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000950
Manuel Pégourié-Gonnard74ca84a2020-01-29 09:46:49 +0100951#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200952
Valerio Setti43363f52022-12-14 08:53:23 +0100953static int mbedtls_sha512_common_self_test( int verbose, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000954{
Valerio Setti43363f52022-12-14 08:53:23 +0100955 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500956 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200957 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000959
Valerio Setti43363f52022-12-14 08:53:23 +0100960#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Valerio Setti326cf462022-12-23 14:57:18 +0100961 sha_test_sum_t* sha_test_sum = ( is384 ) ? sha384_test_sum : sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100962#elif defined(MBEDTLS_SHA512_C)
Valerio Setti326cf462022-12-23 14:57:18 +0100963 sha_test_sum_t* sha_test_sum = sha512_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100964#else
Valerio Setti326cf462022-12-23 14:57:18 +0100965 sha_test_sum_t* sha_test_sum = sha384_test_sum;
Valerio Setti43363f52022-12-14 08:53:23 +0100966#endif
967
Russ Butlerbb83b422016-10-12 17:36:50 -0500968 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
969 if( NULL == buf )
970 {
971 if( verbose != 0 )
972 mbedtls_printf( "Buffer allocation failed\n" );
973
974 return( 1 );
975 }
976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200978
Valerio Setti43363f52022-12-14 08:53:23 +0100979 for( i = 0; i < 3; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000980 {
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 if( verbose != 0 )
Valerio Setti43363f52022-12-14 08:53:23 +0100982 mbedtls_printf( " SHA-%d test #%d: ", 512 - is384 * 128, i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000983
Valerio Setti43363f52022-12-14 08:53:23 +0100984 if( ( ret = mbedtls_sha512_starts( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100985 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000986
Valerio Setti43363f52022-12-14 08:53:23 +0100987 if( i == 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000988 {
989 memset( buf, 'a', buflen = 1000 );
990
Valerio Setti43363f52022-12-14 08:53:23 +0100991 for( int j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100992 {
TRodziewicz26371e42021-06-08 16:45:41 +0200993 ret = mbedtls_sha512_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100994 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100995 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100996 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000997 }
998 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100999 {
Valerio Setti43363f52022-12-14 08:53:23 +01001000 ret = mbedtls_sha512_update( &ctx, sha_test_buf[i],
1001 sha_test_buflen[i] );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001002 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001003 goto fail;
1004 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001005
TRodziewicz26371e42021-06-08 16:45:41 +02001006 if( ( ret = mbedtls_sha512_finish( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001007 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +00001008
Valerio Setti43363f52022-12-14 08:53:23 +01001009 if( memcmp( sha512sum, sha_test_sum[i], 64 - is384 * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001010 {
1011 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001012 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001013 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001014
1015 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001017 }
1018
1019 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001021
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001022 goto exit;
1023
1024fail:
1025 if( verbose != 0 )
1026 mbedtls_printf( "failed\n" );
1027
Paul Bakker5b4af392014-06-26 12:09:34 +02001028exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -05001030 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +02001031
1032 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001033}
1034
Valerio Setti898e7a32022-12-14 08:55:53 +01001035#if defined(MBEDTLS_SHA512_C)
Valerio Setti43363f52022-12-14 08:53:23 +01001036int mbedtls_sha512_self_test( int verbose )
1037{
1038 return mbedtls_sha512_common_self_test( verbose, 0 );
1039}
Valerio Setti898e7a32022-12-14 08:55:53 +01001040#endif /* MBEDTLS_SHA512_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001041
Valerio Setti898e7a32022-12-14 08:55:53 +01001042#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +01001043int mbedtls_sha384_self_test( int verbose )
1044{
1045 return mbedtls_sha512_common_self_test( verbose, 1 );
1046}
Valerio Setti898e7a32022-12-14 08:55:53 +01001047#endif /* MBEDTLS_SHA384_C */
Valerio Setti43363f52022-12-14 08:53:23 +01001048
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001049#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001052
Valerio Setti43363f52022-12-14 08:53:23 +01001053#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */