blob: fa24fb9c8e81aadab681b35bb72f17a7f96bd0f7 [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
107#ifndef asm
108#define asm __asm__
109#endif
110
111static jmp_buf return_from_sigill;
112
113/*
114 * A64 SHA512 support detection via SIGILL
115 */
116static void sigill_handler( int signal )
117{
118 (void) signal;
119 longjmp( return_from_sigill, 1 );
120}
121
122static int mbedtls_a64_crypto_sha512_determine_support( void )
123{
124 struct sigaction old_action, new_action;
125
126 sigset_t old_mask;
127 if( sigprocmask( 0, NULL, &old_mask ) )
128 return( 0 );
129
130 sigemptyset( &new_action.sa_mask );
131 new_action.sa_flags = 0;
132 new_action.sa_handler = sigill_handler;
133
134 sigaction( SIGILL, &new_action, &old_action );
135
136 static int ret = 0;
137
138 if( setjmp( return_from_sigill ) == 0 ) /* First return only */
139 {
140 /* If this traps, we will return a second time from setjmp() with 1 */
141 asm( "sha512h q0, q0, v0.2d" : : : "v0" );
142 ret = 1;
143 }
144
145 sigaction( SIGILL, &old_action, NULL );
146 sigprocmask( SIG_SETMASK, &old_mask, NULL );
147
148 return( ret );
149}
150#else
151#warning "No mechanism to detect A64_CRYPTO found, using C code only"
152#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
153#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
154
155#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
156
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200157#if !defined(MBEDTLS_SHA512_ALT)
158
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000159#define SHA512_BLOCK_SIZE 128
160
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200161#if defined(MBEDTLS_SHA512_SMALLER)
162static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
163{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100164 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200165}
166#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100167#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200168#endif /* MBEDTLS_SHA512_SMALLER */
169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200171{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200173}
174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200176{
177 if( ctx == NULL )
178 return;
179
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500180 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200181}
182
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200183void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
184 const mbedtls_sha512_context *src )
185{
186 *dst = *src;
187}
188
Paul Bakker5121ce52009-01-03 21:22:43 +0000189/*
190 * SHA-512 context setup
191 */
TRodziewicz26371e42021-06-08 16:45:41 +0200192int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000193{
Valerio Setti43363f52022-12-14 08:53:23 +0100194#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100195 if( is384 != 0 && is384 != 1 )
196 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Valerio Setti43363f52022-12-14 08:53:23 +0100197#elif defined(MBEDTLS_SHA512_C)
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100198 if( is384 != 0 )
199 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Valerio Setti43363f52022-12-14 08:53:23 +0100200#else /* defined MBEDTLS_SHA384_C only */
201 if( is384 == 0 )
202 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100203#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000204
Paul Bakker5121ce52009-01-03 21:22:43 +0000205 ctx->total[0] = 0;
206 ctx->total[1] = 0;
207
208 if( is384 == 0 )
209 {
Valerio Setti43363f52022-12-14 08:53:23 +0100210#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 ctx->state[0] = UL64(0x6A09E667F3BCC908);
212 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
213 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
214 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
215 ctx->state[4] = UL64(0x510E527FADE682D1);
216 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
217 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
218 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Valerio Setti43363f52022-12-14 08:53:23 +0100219#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000220 }
221 else
222 {
Valerio Setti43363f52022-12-14 08:53:23 +0100223#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000224 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
225 ctx->state[1] = UL64(0x629A292A367CD507);
226 ctx->state[2] = UL64(0x9159015A3070DD17);
227 ctx->state[3] = UL64(0x152FECD8F70E5939);
228 ctx->state[4] = UL64(0x67332667FFC00B31);
229 ctx->state[5] = UL64(0x8EB44A8768581511);
230 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
231 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200232#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 }
234
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200235#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000236 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200237#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100238
239 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000240}
241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200243
244/*
245 * Round constants
246 */
247static const uint64_t K[80] =
248{
249 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
250 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
251 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
252 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
253 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
254 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
255 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
256 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
257 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
258 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
259 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
260 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
261 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
262 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
263 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
264 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
265 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
266 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
267 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
268 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
269 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
270 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
271 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
272 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
273 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
274 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
275 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
276 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
277 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
278 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
279 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
280 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
281 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
282 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
283 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
284 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
285 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
286 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
287 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
288 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
289};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000290#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200291
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000292#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
293 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
294
295#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
296# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
297# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
298#endif
299
300#ifndef asm
301#define asm __asm__
302#endif
303
304/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
305 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
306 */
307
308#if defined(__clang__) && \
309 (__clang_major__ < 13 || \
310 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
311static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
312{
313 asm( "sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y) );
314 return( x );
315}
316static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
317{
318 asm( "sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
319 return( x );
320}
321static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
322{
323 asm( "sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
324 return( x );
325}
326static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
327{
328 asm( "sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
329 return( x );
330}
331#endif /* __clang__ etc */
332
333static size_t mbedtls_internal_sha512_process_many_a64_crypto(
334 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len )
335{
336 uint64x2_t ab = vld1q_u64( &ctx->state[0] );
337 uint64x2_t cd = vld1q_u64( &ctx->state[2] );
338 uint64x2_t ef = vld1q_u64( &ctx->state[4] );
339 uint64x2_t gh = vld1q_u64( &ctx->state[6] );
340
341 size_t processed = 0;
342
343 for ( ;
344 len >= SHA512_BLOCK_SIZE;
345 processed += SHA512_BLOCK_SIZE,
346 msg += SHA512_BLOCK_SIZE,
347 len -= SHA512_BLOCK_SIZE )
348 {
349 uint64x2_t initial_sum, sum, intermed;
350
351 uint64x2_t ab_orig = ab;
352 uint64x2_t cd_orig = cd;
353 uint64x2_t ef_orig = ef;
354 uint64x2_t gh_orig = gh;
355
356 uint64x2_t s0 = (uint64x2_t) vld1q_u8( msg + 16 * 0 );
357 uint64x2_t s1 = (uint64x2_t) vld1q_u8( msg + 16 * 1 );
358 uint64x2_t s2 = (uint64x2_t) vld1q_u8( msg + 16 * 2 );
359 uint64x2_t s3 = (uint64x2_t) vld1q_u8( msg + 16 * 3 );
360 uint64x2_t s4 = (uint64x2_t) vld1q_u8( msg + 16 * 4 );
361 uint64x2_t s5 = (uint64x2_t) vld1q_u8( msg + 16 * 5 );
362 uint64x2_t s6 = (uint64x2_t) vld1q_u8( msg + 16 * 6 );
363 uint64x2_t s7 = (uint64x2_t) vld1q_u8( msg + 16 * 7 );
364
365#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
366 s0 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s0 ) ) );
367 s1 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s1 ) ) );
368 s2 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s2 ) ) );
369 s3 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s3 ) ) );
370 s4 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s4 ) ) );
371 s5 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s5 ) ) );
372 s6 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s6 ) ) );
373 s7 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s7 ) ) );
374#endif
375
376 /* Rounds 0 and 1 */
377 initial_sum = vaddq_u64( s0, vld1q_u64( &K[0] ) );
378 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
379 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
380 gh = vsha512h2q_u64( intermed, cd, ab );
381 cd = vaddq_u64( cd, intermed );
382
383 /* Rounds 2 and 3 */
384 initial_sum = vaddq_u64( s1, vld1q_u64( &K[2] ) );
385 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
386 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
387 ef = vsha512h2q_u64( intermed, ab, gh );
388 ab = vaddq_u64( ab, intermed );
389
390 /* Rounds 4 and 5 */
391 initial_sum = vaddq_u64( s2, vld1q_u64( &K[4] ) );
392 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
393 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
394 cd = vsha512h2q_u64( intermed, gh, ef );
395 gh = vaddq_u64( gh, intermed );
396
397 /* Rounds 6 and 7 */
398 initial_sum = vaddq_u64( s3, vld1q_u64( &K[6] ) );
399 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
400 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
401 ab = vsha512h2q_u64( intermed, ef, cd );
402 ef = vaddq_u64( ef, intermed );
403
404 /* Rounds 8 and 9 */
405 initial_sum = vaddq_u64( s4, vld1q_u64( &K[8] ) );
406 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
407 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
408 gh = vsha512h2q_u64( intermed, cd, ab );
409 cd = vaddq_u64( cd, intermed );
410
411 /* Rounds 10 and 11 */
412 initial_sum = vaddq_u64( s5, vld1q_u64( &K[10] ) );
413 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
414 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
415 ef = vsha512h2q_u64( intermed, ab, gh );
416 ab = vaddq_u64( ab, intermed );
417
418 /* Rounds 12 and 13 */
419 initial_sum = vaddq_u64( s6, vld1q_u64( &K[12] ) );
420 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
421 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
422 cd = vsha512h2q_u64( intermed, gh, ef );
423 gh = vaddq_u64( gh, intermed );
424
425 /* Rounds 14 and 15 */
426 initial_sum = vaddq_u64( s7, vld1q_u64( &K[14] ) );
427 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
428 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
429 ab = vsha512h2q_u64( intermed, ef, cd );
430 ef = vaddq_u64( ef, intermed );
431
432 for ( unsigned int t = 16; t < 80; t += 16 )
433 {
434 /* Rounds t and t + 1 */
435 s0 = vsha512su1q_u64( vsha512su0q_u64( s0, s1 ), s7, vextq_u64( s4, s5, 1 ) );
436 initial_sum = vaddq_u64( s0, vld1q_u64( &K[t] ) );
437 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
438 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
439 gh = vsha512h2q_u64( intermed, cd, ab );
440 cd = vaddq_u64( cd, intermed );
441
442 /* Rounds t + 2 and t + 3 */
443 s1 = vsha512su1q_u64( vsha512su0q_u64( s1, s2 ), s0, vextq_u64( s5, s6, 1 ) );
444 initial_sum = vaddq_u64( s1, vld1q_u64( &K[t + 2] ) );
445 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
446 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
447 ef = vsha512h2q_u64( intermed, ab, gh );
448 ab = vaddq_u64( ab, intermed );
449
450 /* Rounds t + 4 and t + 5 */
451 s2 = vsha512su1q_u64( vsha512su0q_u64( s2, s3 ), s1, vextq_u64( s6, s7, 1 ) );
452 initial_sum = vaddq_u64( s2, vld1q_u64( &K[t + 4] ) );
453 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
454 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
455 cd = vsha512h2q_u64( intermed, gh, ef );
456 gh = vaddq_u64( gh, intermed );
457
458 /* Rounds t + 6 and t + 7 */
459 s3 = vsha512su1q_u64( vsha512su0q_u64( s3, s4 ), s2, vextq_u64( s7, s0, 1 ) );
460 initial_sum = vaddq_u64( s3, vld1q_u64( &K[t + 6] ) );
461 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
462 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
463 ab = vsha512h2q_u64( intermed, ef, cd );
464 ef = vaddq_u64( ef, intermed );
465
466 /* Rounds t + 8 and t + 9 */
467 s4 = vsha512su1q_u64( vsha512su0q_u64( s4, s5 ), s3, vextq_u64( s0, s1, 1 ) );
468 initial_sum = vaddq_u64( s4, vld1q_u64( &K[t + 8] ) );
469 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
470 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
471 gh = vsha512h2q_u64( intermed, cd, ab );
472 cd = vaddq_u64( cd, intermed );
473
474 /* Rounds t + 10 and t + 11 */
475 s5 = vsha512su1q_u64( vsha512su0q_u64( s5, s6 ), s4, vextq_u64( s1, s2, 1 ) );
476 initial_sum = vaddq_u64( s5, vld1q_u64( &K[t + 10] ) );
477 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
478 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
479 ef = vsha512h2q_u64( intermed, ab, gh );
480 ab = vaddq_u64( ab, intermed );
481
482 /* Rounds t + 12 and t + 13 */
483 s6 = vsha512su1q_u64( vsha512su0q_u64( s6, s7 ), s5, vextq_u64( s2, s3, 1 ) );
484 initial_sum = vaddq_u64( s6, vld1q_u64( &K[t + 12] ) );
485 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
486 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
487 cd = vsha512h2q_u64( intermed, gh, ef );
488 gh = vaddq_u64( gh, intermed );
489
490 /* Rounds t + 14 and t + 15 */
491 s7 = vsha512su1q_u64( vsha512su0q_u64( s7, s0 ), s6, vextq_u64( s3, s4, 1 ) );
492 initial_sum = vaddq_u64( s7, vld1q_u64( &K[t + 14] ) );
493 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
494 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
495 ab = vsha512h2q_u64( intermed, ef, cd );
496 ef = vaddq_u64( ef, intermed );
497 }
498
499 ab = vaddq_u64( ab, ab_orig );
500 cd = vaddq_u64( cd, cd_orig );
501 ef = vaddq_u64( ef, ef_orig );
502 gh = vaddq_u64( gh, gh_orig );
503 }
504
505 vst1q_u64( &ctx->state[0], ab );
506 vst1q_u64( &ctx->state[2], cd );
507 vst1q_u64( &ctx->state[4], ef );
508 vst1q_u64( &ctx->state[6], gh );
509
510 return( processed );
511}
512
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100513#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
514/*
515 * This function is for internal use only if we are building both C and A64
516 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
517 */
518static
519#endif
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000520int mbedtls_internal_sha512_process_a64_crypto( mbedtls_sha512_context *ctx,
521 const unsigned char data[SHA512_BLOCK_SIZE] )
522{
523 return( mbedtls_internal_sha512_process_many_a64_crypto( ctx, data,
524 SHA512_BLOCK_SIZE ) == SHA512_BLOCK_SIZE ) ? 0 : -1;
525}
526
527#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
528
529
530#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
531#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
532#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
533#endif
534
535
536#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
537
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100538#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
539/*
540 * This function is for internal use only if we are building both C and A64
541 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
542 */
543static
544#endif
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000545int mbedtls_internal_sha512_process_c( mbedtls_sha512_context *ctx,
546 const unsigned char data[SHA512_BLOCK_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000547{
548 int i;
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200549 struct
550 {
551 uint64_t temp1, temp2, W[80];
552 uint64_t A[8];
553 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
Hanno Becker1eeca412018-10-15 12:01:35 +0100555#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000556#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
558#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
559#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
560
561#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
562#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
563
Hanno Becker1eeca412018-10-15 12:01:35 +0100564#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
565#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200567#define P(a,b,c,d,e,f,g,h,x,K) \
568 do \
569 { \
570 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
571 local.temp2 = S2(a) + F0((a),(b),(c)); \
572 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100573 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200575 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200576 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200577
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200578#if defined(MBEDTLS_SHA512_SMALLER)
579 for( i = 0; i < 80; i++ )
580 {
581 if( i < 16 )
582 {
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100583 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200584 }
585 else
586 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200587 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
588 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200589 }
590
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200591 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
592 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200593
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200594 local.temp1 = local.A[7]; local.A[7] = local.A[6];
595 local.A[6] = local.A[5]; local.A[5] = local.A[4];
596 local.A[4] = local.A[3]; local.A[3] = local.A[2];
597 local.A[2] = local.A[1]; local.A[1] = local.A[0];
598 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200599 }
600#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 for( i = 0; i < 16; i++ )
602 {
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100603 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000604 }
605
606 for( ; i < 80; i++ )
607 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200608 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
609 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000610 }
611
Paul Bakker5121ce52009-01-03 21:22:43 +0000612 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000613 do
614 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200615 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
616 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
617 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
618 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
619 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
620 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
621 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
622 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
623 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
624 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
625 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
626 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
627 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
628 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
629 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
630 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 }
632 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200633#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200635 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200636 ctx->state[i] += local.A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100637
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200638 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200639 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100640
641 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000642}
Jaeden Amero041039f2018-02-19 15:28:08 +0000643
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000644#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
645
646
647#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
648
649static size_t mbedtls_internal_sha512_process_many_c(
650 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
651{
652 size_t processed = 0;
653
654 while( len >= SHA512_BLOCK_SIZE )
655 {
656 if( mbedtls_internal_sha512_process_c( ctx, data ) != 0)
657 return( 0 );
658
659 data += SHA512_BLOCK_SIZE;
660 len -= SHA512_BLOCK_SIZE;
661
662 processed += SHA512_BLOCK_SIZE;
663 }
664
665 return( processed );
666}
667
668#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
669
670
671#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
672
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100673static int mbedtls_a64_crypto_sha512_has_support( void )
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000674{
675 static int done = 0;
676 static int supported = 0;
677
678 if( !done )
679 {
680 supported = mbedtls_a64_crypto_sha512_determine_support();
681 done = 1;
682 }
683
684 return( supported );
685}
686
687static size_t mbedtls_internal_sha512_process_many( mbedtls_sha512_context *ctx,
688 const uint8_t *msg, size_t len )
689{
690 if( mbedtls_a64_crypto_sha512_has_support() )
691 return( mbedtls_internal_sha512_process_many_a64_crypto( ctx, msg, len ) );
692 else
693 return( mbedtls_internal_sha512_process_many_c( ctx, msg, len ) );
694}
695
696int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
697 const unsigned char data[SHA512_BLOCK_SIZE] )
698{
699 if( mbedtls_a64_crypto_sha512_has_support() )
700 return( mbedtls_internal_sha512_process_a64_crypto( ctx, data ) );
701 else
702 return( mbedtls_internal_sha512_process_c( ctx, data ) );
703}
704
705#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
707/*
708 * SHA-512 process buffer
709 */
TRodziewicz26371e42021-06-08 16:45:41 +0200710int mbedtls_sha512_update( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100711 const unsigned char *input,
712 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000713{
Janos Follath24eed8d2019-11-22 13:21:35 +0000714 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000715 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000716 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
Brian White12895d12014-04-11 11:29:42 -0400718 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100719 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000720
Paul Bakkerb8213a12011-07-11 08:16:18 +0000721 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000722 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000723
Paul Bakker5c2364c2012-10-01 14:41:15 +0000724 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000725
Paul Bakker5c2364c2012-10-01 14:41:15 +0000726 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000727 ctx->total[1]++;
728
729 if( left && ilen >= fill )
730 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200731 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100732
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100733 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100734 return( ret );
735
Paul Bakker5121ce52009-01-03 21:22:43 +0000736 input += fill;
737 ilen -= fill;
738 left = 0;
739 }
740
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000741 while( ilen >= SHA512_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000742 {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000743 size_t processed =
744 mbedtls_internal_sha512_process_many( ctx, input, ilen );
745 if( processed < SHA512_BLOCK_SIZE )
746 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100747
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000748 input += processed;
749 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 }
751
752 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200753 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100754
755 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000756}
757
Paul Bakker5121ce52009-01-03 21:22:43 +0000758/*
759 * SHA-512 final digest
760 */
TRodziewicz26371e42021-06-08 16:45:41 +0200761int mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
Gilles Peskinee02e02f2021-05-13 00:22:35 +0200762 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000763{
Janos Follath24eed8d2019-11-22 13:21:35 +0000764 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200765 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000766 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000767
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200768 /*
769 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
770 */
771 used = ctx->total[0] & 0x7F;
772
773 ctx->buffer[used++] = 0x80;
774
775 if( used <= 112 )
776 {
777 /* Enough room for padding + length in current block */
778 memset( ctx->buffer + used, 0, 112 - used );
779 }
780 else
781 {
782 /* We'll need an extra block */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000783 memset( ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200784
785 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
786 return( ret );
787
788 memset( ctx->buffer, 0, 112 );
789 }
790
791 /*
792 * Add message length
793 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 high = ( ctx->total[0] >> 61 )
795 | ( ctx->total[1] << 3 );
796 low = ( ctx->total[0] << 3 );
797
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200798 sha512_put_uint64_be( high, ctx->buffer, 112 );
799 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000800
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200801 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
802 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000803
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200804 /*
805 * Output final state
806 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200807 sha512_put_uint64_be( ctx->state[0], output, 0 );
808 sha512_put_uint64_be( ctx->state[1], output, 8 );
809 sha512_put_uint64_be( ctx->state[2], output, 16 );
810 sha512_put_uint64_be( ctx->state[3], output, 24 );
811 sha512_put_uint64_be( ctx->state[4], output, 32 );
812 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
David Horstmann2788f6b2022-10-06 18:45:09 +0100814 int truncated = 0;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200815#if defined(MBEDTLS_SHA384_C)
David Horstmann2788f6b2022-10-06 18:45:09 +0100816 truncated = ctx->is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200817#endif
David Horstmann2788f6b2022-10-06 18:45:09 +0100818 if( !truncated )
Paul Bakker5121ce52009-01-03 21:22:43 +0000819 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200820 sha512_put_uint64_be( ctx->state[6], output, 48 );
821 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000822 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100823
824 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000825}
826
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200828
Paul Bakker5121ce52009-01-03 21:22:43 +0000829/*
830 * output = SHA-512( input buffer )
831 */
TRodziewicz26371e42021-06-08 16:45:41 +0200832int mbedtls_sha512( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100833 size_t ilen,
Gilles Peskinee02e02f2021-05-13 00:22:35 +0200834 unsigned char *output,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100835 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000836{
Janos Follath24eed8d2019-11-22 13:21:35 +0000837 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
Valerio Setti43363f52022-12-14 08:53:23 +0100840#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100841 if( is384 != 0 && is384 != 1 )
842 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Valerio Setti43363f52022-12-14 08:53:23 +0100843#elif defined(MBEDTLS_SHA512_C)
Tuvshinzaya Erdenekhuu5893ab02022-08-05 15:59:19 +0100844 if( is384 != 0 )
845 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Valerio Setti43363f52022-12-14 08:53:23 +0100846#else /* defined MBEDTLS_SHA384_C only */
847 if( is384 == 0 )
848 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100849#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000850
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100852
TRodziewicz26371e42021-06-08 16:45:41 +0200853 if( ( ret = mbedtls_sha512_starts( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100854 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100855
TRodziewicz26371e42021-06-08 16:45:41 +0200856 if( ( ret = mbedtls_sha512_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100857 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100858
TRodziewicz26371e42021-06-08 16:45:41 +0200859 if( ( ret = mbedtls_sha512_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100860 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100861
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100862exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100864
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100865 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000866}
867
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
870/*
871 * FIPS-180-2 test vectors
872 */
Valerio Setti43363f52022-12-14 08:53:23 +0100873static const unsigned char sha_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000874{
875 { "abc" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200876 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000877 { "" }
878};
879
Valerio Setti43363f52022-12-14 08:53:23 +0100880static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000881{
882 3, 112, 1000
883};
884
Valerio Setti43363f52022-12-14 08:53:23 +0100885typedef const unsigned char (sha_test_sum_t)[64];
886
887/*
888 * SHA-384 test vectors
889 */
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200890#if defined(MBEDTLS_SHA384_C)
Valerio Setti43363f52022-12-14 08:53:23 +0100891static sha_test_sum_t sha384_test_sum[] =
892{
Paul Bakker5121ce52009-01-03 21:22:43 +0000893 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
894 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
895 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
896 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
897 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
898 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
899 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
900 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
901 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
902 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
903 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
904 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
905 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
906 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
907 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
908 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
909 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
Valerio Setti43363f52022-12-14 08:53:23 +0100910 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }
911};
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200912#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000913
Valerio Setti43363f52022-12-14 08:53:23 +0100914/*
915 * SHA-512 test vectors
916 */
917#if defined(MBEDTLS_SHA512_C)
918static sha_test_sum_t sha512_test_sum[] =
919{
Paul Bakker5121ce52009-01-03 21:22:43 +0000920 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
921 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
922 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
923 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
924 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
925 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
926 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
927 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
928 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
929 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
930 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
931 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
932 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
933 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
934 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
935 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
936 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
937 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
938 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
939 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
940 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
941 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
942 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
943 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
944};
Valerio Setti43363f52022-12-14 08:53:23 +0100945#endif /* MBEDTLS_SHA512_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Manuel Pégourié-Gonnard74ca84a2020-01-29 09:46:49 +0100947#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200948
Valerio Setti43363f52022-12-14 08:53:23 +0100949static int mbedtls_sha512_common_self_test( int verbose, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000950{
Valerio Setti43363f52022-12-14 08:53:23 +0100951 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500952 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200953 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000955
Valerio Setti43363f52022-12-14 08:53:23 +0100956 sha_test_sum_t* sha_test_sum;
957
958 sha_test_sum =
959#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C)
960 ( is384 ) ? sha384_test_sum : sha512_test_sum;
961#elif defined(MBEDTLS_SHA512_C)
962 sha512_test_sum;
963#else
964 sha384_test_sum;
965#endif
966
Russ Butlerbb83b422016-10-12 17:36:50 -0500967 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
968 if( NULL == buf )
969 {
970 if( verbose != 0 )
971 mbedtls_printf( "Buffer allocation failed\n" );
972
973 return( 1 );
974 }
975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200977
Valerio Setti43363f52022-12-14 08:53:23 +0100978 for( i = 0; i < 3; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000979 {
Paul Bakker5121ce52009-01-03 21:22:43 +0000980 if( verbose != 0 )
Valerio Setti43363f52022-12-14 08:53:23 +0100981 mbedtls_printf( " SHA-%d test #%d: ", 512 - is384 * 128, i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000982
Valerio Setti43363f52022-12-14 08:53:23 +0100983 if( ( ret = mbedtls_sha512_starts( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100984 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000985
Valerio Setti43363f52022-12-14 08:53:23 +0100986 if( i == 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000987 {
988 memset( buf, 'a', buflen = 1000 );
989
Valerio Setti43363f52022-12-14 08:53:23 +0100990 for( int j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100991 {
TRodziewicz26371e42021-06-08 16:45:41 +0200992 ret = mbedtls_sha512_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100993 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100994 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100995 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000996 }
997 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100998 {
Valerio Setti43363f52022-12-14 08:53:23 +0100999 ret = mbedtls_sha512_update( &ctx, sha_test_buf[i],
1000 sha_test_buflen[i] );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001001 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001002 goto fail;
1003 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001004
TRodziewicz26371e42021-06-08 16:45:41 +02001005 if( ( ret = mbedtls_sha512_finish( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001006 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +00001007
Valerio Setti43363f52022-12-14 08:53:23 +01001008 if( memcmp( sha512sum, sha_test_sum[i], 64 - is384 * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001009 {
1010 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001011 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001013
1014 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001015 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001016 }
1017
1018 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001021 goto exit;
1022
1023fail:
1024 if( verbose != 0 )
1025 mbedtls_printf( "failed\n" );
1026
Paul Bakker5b4af392014-06-26 12:09:34 +02001027exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -05001029 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +02001030
1031 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001032}
1033
Valerio Setti43363f52022-12-14 08:53:23 +01001034int mbedtls_sha512_self_test( int verbose )
1035{
1036 return mbedtls_sha512_common_self_test( verbose, 0 );
1037}
1038
1039int mbedtls_sha384_self_test( int verbose )
1040{
1041 return mbedtls_sha512_common_self_test( verbose, 1 );
1042}
1043
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001044#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001047
Valerio Setti43363f52022-12-14 08:53:23 +01001048#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */