blob: be03ec3316b016d95d0994129fc83aaa2a9a80eb [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_SHA512_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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_SELF_TEST)
42#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#else
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050046#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050048#define mbedtls_calloc calloc
49#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Tom Cosgrove87fbfb52022-03-15 10:51:52 +000053#if defined(__aarch64__)
54# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
55 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
56# include <arm_neon.h>
57# endif
58# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
59# if defined(__unix__)
60# if defined(__linux__)
61 /* Our preferred method of detection is getauxval() */
62# include <sys/auxv.h>
63# endif
64 /* Use SIGILL on Unix, and fall back to it on Linux */
65# include <signal.h>
66# endif
67# endif
68#elif defined(_M_ARM64)
69# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
70 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
71# include <arm64_neon.h>
72# endif
73#else
74# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
75# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
76#endif
77
78#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
79/*
80 * Capability detection code comes early, so we can disable
81 * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
82 */
83#if defined(HWCAP_SHA512)
84static int mbedtls_a64_crypto_sha512_determine_support( void )
85{
86 return( ( getauxval( AT_HWCAP ) & HWCAP_SHA512 ) ? 1 : 0 );
87}
88#elif defined(__APPLE__)
89#include <sys/types.h>
90#include <sys/sysctl.h>
91
92static int mbedtls_a64_crypto_sha512_determine_support( void )
93{
94 int value = 0;
95 size_t value_len = sizeof(value);
96
97 int ret = sysctlbyname( "hw.optional.armv8_2_sha512", &value, &value_len,
98 NULL, 0 );
99 return( ret == 0 && value != 0 );
100}
101#elif defined(_M_ARM64)
102/*
103 * As of March 2022, there don't appear to be any PF_ARM_V8_* flags
104 * available to pass to IsProcessorFeaturePresent() to check for
105 * SHA-512 support. So we fall back to the C code only.
106 */
107#if defined(_MSC_VER)
108#pragma message "No mechanism to detect A64_CRYPTO found, using C code only"
109#else
110#warning "No mechanism to detect A64_CRYPTO found, using C code only"
111#endif
112#elif defined(__unix__) && defined(SIG_SETMASK)
113/* Detection with SIGILL, setjmp() and longjmp() */
114#include <signal.h>
115#include <setjmp.h>
116
117#ifndef asm
118#define asm __asm__
119#endif
120
121static jmp_buf return_from_sigill;
122
123/*
124 * A64 SHA512 support detection via SIGILL
125 */
126static void sigill_handler( int signal )
127{
128 (void) signal;
129 longjmp( return_from_sigill, 1 );
130}
131
132static int mbedtls_a64_crypto_sha512_determine_support( void )
133{
134 struct sigaction old_action, new_action;
135
136 sigset_t old_mask;
137 if( sigprocmask( 0, NULL, &old_mask ) )
138 return( 0 );
139
140 sigemptyset( &new_action.sa_mask );
141 new_action.sa_flags = 0;
142 new_action.sa_handler = sigill_handler;
143
144 sigaction( SIGILL, &new_action, &old_action );
145
146 static int ret = 0;
147
148 if( setjmp( return_from_sigill ) == 0 ) /* First return only */
149 {
150 /* If this traps, we will return a second time from setjmp() with 1 */
151 asm( "sha512h q0, q0, v0.2d" : : : "v0" );
152 ret = 1;
153 }
154
155 sigaction( SIGILL, &old_action, NULL );
156 sigprocmask( SIG_SETMASK, &old_mask, NULL );
157
158 return( ret );
159}
160#else
161#warning "No mechanism to detect A64_CRYPTO found, using C code only"
162#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
163#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */
164
165#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
166
Hanno Beckerc7560492018-12-20 10:23:39 +0000167#define SHA512_VALIDATE_RET(cond) \
168 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
169#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
170
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200171#if !defined(MBEDTLS_SHA512_ALT)
172
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000173#define SHA512_BLOCK_SIZE 128
174
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200175#if defined(MBEDTLS_SHA512_SMALLER)
176static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
177{
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100178 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200179}
180#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100181#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200182#endif /* MBEDTLS_SHA512_SMALLER */
183
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200184void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200185{
Hanno Becker38e15d42018-12-18 17:54:00 +0000186 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000187
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200189}
190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200192{
193 if( ctx == NULL )
194 return;
195
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500196 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200197}
198
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200199void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
200 const mbedtls_sha512_context *src )
201{
Hanno Becker38e15d42018-12-18 17:54:00 +0000202 SHA512_VALIDATE( dst != NULL );
203 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000204
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200205 *dst = *src;
206}
207
Paul Bakker5121ce52009-01-03 21:22:43 +0000208/*
209 * SHA-512 context setup
210 */
TRodziewicz26371e42021-06-08 16:45:41 +0200211int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000212{
Hanno Becker38e15d42018-12-18 17:54:00 +0000213 SHA512_VALIDATE_RET( ctx != NULL );
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200214#if defined(MBEDTLS_SHA384_C)
Hanno Becker38e15d42018-12-18 17:54:00 +0000215 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100216#else
217 SHA512_VALIDATE_RET( is384 == 0 );
218#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000219
Paul Bakker5121ce52009-01-03 21:22:43 +0000220 ctx->total[0] = 0;
221 ctx->total[1] = 0;
222
223 if( is384 == 0 )
224 {
225 /* SHA-512 */
226 ctx->state[0] = UL64(0x6A09E667F3BCC908);
227 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
228 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
229 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
230 ctx->state[4] = UL64(0x510E527FADE682D1);
231 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
232 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
233 ctx->state[7] = UL64(0x5BE0CD19137E2179);
234 }
235 else
236 {
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200237#if !defined(MBEDTLS_SHA384_C)
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200238 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
239#else
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 /* SHA-384 */
241 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
242 ctx->state[1] = UL64(0x629A292A367CD507);
243 ctx->state[2] = UL64(0x9159015A3070DD17);
244 ctx->state[3] = UL64(0x152FECD8F70E5939);
245 ctx->state[4] = UL64(0x67332667FFC00B31);
246 ctx->state[5] = UL64(0x8EB44A8768581511);
247 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
248 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200249#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000250 }
251
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200252#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200254#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100255
256 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257}
258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200260
261/*
262 * Round constants
263 */
264static const uint64_t K[80] =
265{
266 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
267 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
268 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
269 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
270 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
271 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
272 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
273 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
274 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
275 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
276 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
277 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
278 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
279 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
280 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
281 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
282 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
283 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
284 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
285 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
286 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
287 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
288 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
289 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
290 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
291 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
292 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
293 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
294 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
295 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
296 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
297 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
298 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
299 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
300 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
301 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
302 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
303 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
304 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
305 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
306};
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000307#endif
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200308
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000309#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
310 defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
311
312#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
313# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many
314# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process
315#endif
316
317#ifndef asm
318#define asm __asm__
319#endif
320
321/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY,
322 * under the MIT licence; dual-licensed as Apache 2 with his kind permission.
323 */
324
325#if defined(__clang__) && \
326 (__clang_major__ < 13 || \
327 (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0))
328static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y)
329{
330 asm( "sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y) );
331 return( x );
332}
333static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
334{
335 asm( "sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
336 return( x );
337}
338static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
339{
340 asm( "sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
341 return( x );
342}
343static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z)
344{
345 asm( "sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z) );
346 return( x );
347}
348#endif /* __clang__ etc */
349
350static size_t mbedtls_internal_sha512_process_many_a64_crypto(
351 mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len )
352{
353 uint64x2_t ab = vld1q_u64( &ctx->state[0] );
354 uint64x2_t cd = vld1q_u64( &ctx->state[2] );
355 uint64x2_t ef = vld1q_u64( &ctx->state[4] );
356 uint64x2_t gh = vld1q_u64( &ctx->state[6] );
357
358 size_t processed = 0;
359
360 for ( ;
361 len >= SHA512_BLOCK_SIZE;
362 processed += SHA512_BLOCK_SIZE,
363 msg += SHA512_BLOCK_SIZE,
364 len -= SHA512_BLOCK_SIZE )
365 {
366 uint64x2_t initial_sum, sum, intermed;
367
368 uint64x2_t ab_orig = ab;
369 uint64x2_t cd_orig = cd;
370 uint64x2_t ef_orig = ef;
371 uint64x2_t gh_orig = gh;
372
373 uint64x2_t s0 = (uint64x2_t) vld1q_u8( msg + 16 * 0 );
374 uint64x2_t s1 = (uint64x2_t) vld1q_u8( msg + 16 * 1 );
375 uint64x2_t s2 = (uint64x2_t) vld1q_u8( msg + 16 * 2 );
376 uint64x2_t s3 = (uint64x2_t) vld1q_u8( msg + 16 * 3 );
377 uint64x2_t s4 = (uint64x2_t) vld1q_u8( msg + 16 * 4 );
378 uint64x2_t s5 = (uint64x2_t) vld1q_u8( msg + 16 * 5 );
379 uint64x2_t s6 = (uint64x2_t) vld1q_u8( msg + 16 * 6 );
380 uint64x2_t s7 = (uint64x2_t) vld1q_u8( msg + 16 * 7 );
381
382#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */
383 s0 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s0 ) ) );
384 s1 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s1 ) ) );
385 s2 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s2 ) ) );
386 s3 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s3 ) ) );
387 s4 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s4 ) ) );
388 s5 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s5 ) ) );
389 s6 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s6 ) ) );
390 s7 = vreinterpretq_u64_u8( vrev64q_u8( vreinterpretq_u8_u64( s7 ) ) );
391#endif
392
393 /* Rounds 0 and 1 */
394 initial_sum = vaddq_u64( s0, vld1q_u64( &K[0] ) );
395 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
396 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
397 gh = vsha512h2q_u64( intermed, cd, ab );
398 cd = vaddq_u64( cd, intermed );
399
400 /* Rounds 2 and 3 */
401 initial_sum = vaddq_u64( s1, vld1q_u64( &K[2] ) );
402 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
403 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
404 ef = vsha512h2q_u64( intermed, ab, gh );
405 ab = vaddq_u64( ab, intermed );
406
407 /* Rounds 4 and 5 */
408 initial_sum = vaddq_u64( s2, vld1q_u64( &K[4] ) );
409 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
410 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
411 cd = vsha512h2q_u64( intermed, gh, ef );
412 gh = vaddq_u64( gh, intermed );
413
414 /* Rounds 6 and 7 */
415 initial_sum = vaddq_u64( s3, vld1q_u64( &K[6] ) );
416 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
417 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
418 ab = vsha512h2q_u64( intermed, ef, cd );
419 ef = vaddq_u64( ef, intermed );
420
421 /* Rounds 8 and 9 */
422 initial_sum = vaddq_u64( s4, vld1q_u64( &K[8] ) );
423 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
424 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
425 gh = vsha512h2q_u64( intermed, cd, ab );
426 cd = vaddq_u64( cd, intermed );
427
428 /* Rounds 10 and 11 */
429 initial_sum = vaddq_u64( s5, vld1q_u64( &K[10] ) );
430 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
431 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
432 ef = vsha512h2q_u64( intermed, ab, gh );
433 ab = vaddq_u64( ab, intermed );
434
435 /* Rounds 12 and 13 */
436 initial_sum = vaddq_u64( s6, vld1q_u64( &K[12] ) );
437 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
438 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
439 cd = vsha512h2q_u64( intermed, gh, ef );
440 gh = vaddq_u64( gh, intermed );
441
442 /* Rounds 14 and 15 */
443 initial_sum = vaddq_u64( s7, vld1q_u64( &K[14] ) );
444 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
445 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
446 ab = vsha512h2q_u64( intermed, ef, cd );
447 ef = vaddq_u64( ef, intermed );
448
449 for ( unsigned int t = 16; t < 80; t += 16 )
450 {
451 /* Rounds t and t + 1 */
452 s0 = vsha512su1q_u64( vsha512su0q_u64( s0, s1 ), s7, vextq_u64( s4, s5, 1 ) );
453 initial_sum = vaddq_u64( s0, vld1q_u64( &K[t] ) );
454 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
455 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
456 gh = vsha512h2q_u64( intermed, cd, ab );
457 cd = vaddq_u64( cd, intermed );
458
459 /* Rounds t + 2 and t + 3 */
460 s1 = vsha512su1q_u64( vsha512su0q_u64( s1, s2 ), s0, vextq_u64( s5, s6, 1 ) );
461 initial_sum = vaddq_u64( s1, vld1q_u64( &K[t + 2] ) );
462 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
463 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
464 ef = vsha512h2q_u64( intermed, ab, gh );
465 ab = vaddq_u64( ab, intermed );
466
467 /* Rounds t + 4 and t + 5 */
468 s2 = vsha512su1q_u64( vsha512su0q_u64( s2, s3 ), s1, vextq_u64( s6, s7, 1 ) );
469 initial_sum = vaddq_u64( s2, vld1q_u64( &K[t + 4] ) );
470 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
471 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
472 cd = vsha512h2q_u64( intermed, gh, ef );
473 gh = vaddq_u64( gh, intermed );
474
475 /* Rounds t + 6 and t + 7 */
476 s3 = vsha512su1q_u64( vsha512su0q_u64( s3, s4 ), s2, vextq_u64( s7, s0, 1 ) );
477 initial_sum = vaddq_u64( s3, vld1q_u64( &K[t + 6] ) );
478 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
479 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
480 ab = vsha512h2q_u64( intermed, ef, cd );
481 ef = vaddq_u64( ef, intermed );
482
483 /* Rounds t + 8 and t + 9 */
484 s4 = vsha512su1q_u64( vsha512su0q_u64( s4, s5 ), s3, vextq_u64( s0, s1, 1 ) );
485 initial_sum = vaddq_u64( s4, vld1q_u64( &K[t + 8] ) );
486 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), gh );
487 intermed = vsha512hq_u64( sum, vextq_u64( ef, gh, 1 ), vextq_u64( cd, ef, 1 ) );
488 gh = vsha512h2q_u64( intermed, cd, ab );
489 cd = vaddq_u64( cd, intermed );
490
491 /* Rounds t + 10 and t + 11 */
492 s5 = vsha512su1q_u64( vsha512su0q_u64( s5, s6 ), s4, vextq_u64( s1, s2, 1 ) );
493 initial_sum = vaddq_u64( s5, vld1q_u64( &K[t + 10] ) );
494 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ef );
495 intermed = vsha512hq_u64( sum, vextq_u64( cd, ef, 1 ), vextq_u64( ab, cd, 1 ) );
496 ef = vsha512h2q_u64( intermed, ab, gh );
497 ab = vaddq_u64( ab, intermed );
498
499 /* Rounds t + 12 and t + 13 */
500 s6 = vsha512su1q_u64( vsha512su0q_u64( s6, s7 ), s5, vextq_u64( s2, s3, 1 ) );
501 initial_sum = vaddq_u64( s6, vld1q_u64( &K[t + 12] ) );
502 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), cd );
503 intermed = vsha512hq_u64( sum, vextq_u64( ab, cd, 1 ), vextq_u64( gh, ab, 1 ) );
504 cd = vsha512h2q_u64( intermed, gh, ef );
505 gh = vaddq_u64( gh, intermed );
506
507 /* Rounds t + 14 and t + 15 */
508 s7 = vsha512su1q_u64( vsha512su0q_u64( s7, s0 ), s6, vextq_u64( s3, s4, 1 ) );
509 initial_sum = vaddq_u64( s7, vld1q_u64( &K[t + 14] ) );
510 sum = vaddq_u64( vextq_u64( initial_sum, initial_sum, 1 ), ab );
511 intermed = vsha512hq_u64( sum, vextq_u64( gh, ab, 1 ), vextq_u64( ef, gh, 1 ) );
512 ab = vsha512h2q_u64( intermed, ef, cd );
513 ef = vaddq_u64( ef, intermed );
514 }
515
516 ab = vaddq_u64( ab, ab_orig );
517 cd = vaddq_u64( cd, cd_orig );
518 ef = vaddq_u64( ef, ef_orig );
519 gh = vaddq_u64( gh, gh_orig );
520 }
521
522 vst1q_u64( &ctx->state[0], ab );
523 vst1q_u64( &ctx->state[2], cd );
524 vst1q_u64( &ctx->state[4], ef );
525 vst1q_u64( &ctx->state[6], gh );
526
527 return( processed );
528}
529
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100530#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
531/*
532 * This function is for internal use only if we are building both C and A64
533 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
534 */
535static
536#endif
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000537int mbedtls_internal_sha512_process_a64_crypto( mbedtls_sha512_context *ctx,
538 const unsigned char data[SHA512_BLOCK_SIZE] )
539{
540 return( mbedtls_internal_sha512_process_many_a64_crypto( ctx, data,
541 SHA512_BLOCK_SIZE ) == SHA512_BLOCK_SIZE ) ? 0 : -1;
542}
543
544#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
545
546
547#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
548#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many
549#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process
550#endif
551
552
553#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
554
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100555#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
556/*
557 * This function is for internal use only if we are building both C and A64
558 * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process()
559 */
560static
561#endif
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000562int mbedtls_internal_sha512_process_c( mbedtls_sha512_context *ctx,
563 const unsigned char data[SHA512_BLOCK_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000564{
565 int i;
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200566 struct
567 {
568 uint64_t temp1, temp2, W[80];
569 uint64_t A[8];
570 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
Hanno Becker38e15d42018-12-18 17:54:00 +0000572 SHA512_VALIDATE_RET( ctx != NULL );
573 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000574
Hanno Becker1eeca412018-10-15 12:01:35 +0100575#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000576#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
578#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
579#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
580
581#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
582#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
583
Hanno Becker1eeca412018-10-15 12:01:35 +0100584#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
585#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000586
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200587#define P(a,b,c,d,e,f,g,h,x,K) \
588 do \
589 { \
590 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
591 local.temp2 = S2(a) + F0((a),(b),(c)); \
592 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100593 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000594
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200595 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200596 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200597
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200598#if defined(MBEDTLS_SHA512_SMALLER)
599 for( i = 0; i < 80; i++ )
600 {
601 if( i < 16 )
602 {
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100603 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200604 }
605 else
606 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200607 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
608 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200609 }
610
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200611 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
612 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200613
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200614 local.temp1 = local.A[7]; local.A[7] = local.A[6];
615 local.A[6] = local.A[5]; local.A[5] = local.A[4];
616 local.A[4] = local.A[3]; local.A[3] = local.A[2];
617 local.A[2] = local.A[1]; local.A[1] = local.A[0];
618 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200619 }
620#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000621 for( i = 0; i < 16; i++ )
622 {
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100623 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 }
625
626 for( ; i < 80; i++ )
627 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200628 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
629 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 }
631
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 do
634 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200635 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
636 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
637 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
638 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
639 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
640 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
641 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
642 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
643 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
644 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
645 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
646 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
647 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
648 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
649 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
650 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 }
652 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200653#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200655 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200656 ctx->state[i] += local.A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100657
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200658 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200659 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100660
661 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000662}
Jaeden Amero041039f2018-02-19 15:28:08 +0000663
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000664#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
665
666
667#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
668
669static size_t mbedtls_internal_sha512_process_many_c(
670 mbedtls_sha512_context *ctx, const uint8_t *data, size_t len)
671{
672 size_t processed = 0;
673
674 while( len >= SHA512_BLOCK_SIZE )
675 {
676 if( mbedtls_internal_sha512_process_c( ctx, data ) != 0)
677 return( 0 );
678
679 data += SHA512_BLOCK_SIZE;
680 len -= SHA512_BLOCK_SIZE;
681
682 processed += SHA512_BLOCK_SIZE;
683 }
684
685 return( processed );
686}
687
688#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
689
690
691#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
692
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100693static int mbedtls_a64_crypto_sha512_has_support( void )
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000694{
695 static int done = 0;
696 static int supported = 0;
697
698 if( !done )
699 {
700 supported = mbedtls_a64_crypto_sha512_determine_support();
701 done = 1;
702 }
703
704 return( supported );
705}
706
707static size_t mbedtls_internal_sha512_process_many( mbedtls_sha512_context *ctx,
708 const uint8_t *msg, size_t len )
709{
710 if( mbedtls_a64_crypto_sha512_has_support() )
711 return( mbedtls_internal_sha512_process_many_a64_crypto( ctx, msg, len ) );
712 else
713 return( mbedtls_internal_sha512_process_many_c( ctx, msg, len ) );
714}
715
716int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
717 const unsigned char data[SHA512_BLOCK_SIZE] )
718{
719 if( mbedtls_a64_crypto_sha512_has_support() )
720 return( mbedtls_internal_sha512_process_a64_crypto( ctx, data ) );
721 else
722 return( mbedtls_internal_sha512_process_c( ctx, data ) );
723}
724
725#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000726
727/*
728 * SHA-512 process buffer
729 */
TRodziewicz26371e42021-06-08 16:45:41 +0200730int mbedtls_sha512_update( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100731 const unsigned char *input,
732 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000733{
Janos Follath24eed8d2019-11-22 13:21:35 +0000734 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000735 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000736 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000737
Hanno Becker38e15d42018-12-18 17:54:00 +0000738 SHA512_VALIDATE_RET( ctx != NULL );
739 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000740
Brian White12895d12014-04-11 11:29:42 -0400741 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100742 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000743
Paul Bakkerb8213a12011-07-11 08:16:18 +0000744 left = (unsigned int) (ctx->total[0] & 0x7F);
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000745 fill = SHA512_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000746
Paul Bakker5c2364c2012-10-01 14:41:15 +0000747 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Paul Bakker5c2364c2012-10-01 14:41:15 +0000749 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 ctx->total[1]++;
751
752 if( left && ilen >= fill )
753 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200754 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100755
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100756 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100757 return( ret );
758
Paul Bakker5121ce52009-01-03 21:22:43 +0000759 input += fill;
760 ilen -= fill;
761 left = 0;
762 }
763
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000764 while( ilen >= SHA512_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000765 {
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000766 size_t processed =
767 mbedtls_internal_sha512_process_many( ctx, input, ilen );
768 if( processed < SHA512_BLOCK_SIZE )
769 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100770
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000771 input += processed;
772 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 }
774
775 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200776 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100777
778 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000779}
780
Paul Bakker5121ce52009-01-03 21:22:43 +0000781/*
782 * SHA-512 final digest
783 */
TRodziewicz26371e42021-06-08 16:45:41 +0200784int mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
Gilles Peskinee02e02f2021-05-13 00:22:35 +0200785 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000786{
Janos Follath24eed8d2019-11-22 13:21:35 +0000787 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200788 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000789 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000790
Hanno Becker38e15d42018-12-18 17:54:00 +0000791 SHA512_VALIDATE_RET( ctx != NULL );
792 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000793
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200794 /*
795 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
796 */
797 used = ctx->total[0] & 0x7F;
798
799 ctx->buffer[used++] = 0x80;
800
801 if( used <= 112 )
802 {
803 /* Enough room for padding + length in current block */
804 memset( ctx->buffer + used, 0, 112 - used );
805 }
806 else
807 {
808 /* We'll need an extra block */
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000809 memset( ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200810
811 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
812 return( ret );
813
814 memset( ctx->buffer, 0, 112 );
815 }
816
817 /*
818 * Add message length
819 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000820 high = ( ctx->total[0] >> 61 )
821 | ( ctx->total[1] << 3 );
822 low = ( ctx->total[0] << 3 );
823
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200824 sha512_put_uint64_be( high, ctx->buffer, 112 );
825 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200827 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
828 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000829
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200830 /*
831 * Output final state
832 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200833 sha512_put_uint64_be( ctx->state[0], output, 0 );
834 sha512_put_uint64_be( ctx->state[1], output, 8 );
835 sha512_put_uint64_be( ctx->state[2], output, 16 );
836 sha512_put_uint64_be( ctx->state[3], output, 24 );
837 sha512_put_uint64_be( ctx->state[4], output, 32 );
838 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200840#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000841 if( ctx->is384 == 0 )
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200842#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000843 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200844 sha512_put_uint64_be( ctx->state[6], output, 48 );
845 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000846 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100847
848 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000849}
850
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200852
Paul Bakker5121ce52009-01-03 21:22:43 +0000853/*
854 * output = SHA-512( input buffer )
855 */
TRodziewicz26371e42021-06-08 16:45:41 +0200856int mbedtls_sha512( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100857 size_t ilen,
Gilles Peskinee02e02f2021-05-13 00:22:35 +0200858 unsigned char *output,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100859 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000860{
Janos Follath24eed8d2019-11-22 13:21:35 +0000861 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200864#if defined(MBEDTLS_SHA384_C)
Hanno Becker38e15d42018-12-18 17:54:00 +0000865 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100866#else
867 SHA512_VALIDATE_RET( is384 == 0 );
868#endif
Hanno Becker38e15d42018-12-18 17:54:00 +0000869 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
870 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000871
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100873
TRodziewicz26371e42021-06-08 16:45:41 +0200874 if( ( ret = mbedtls_sha512_starts( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100875 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100876
TRodziewicz26371e42021-06-08 16:45:41 +0200877 if( ( ret = mbedtls_sha512_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100878 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100879
TRodziewicz26371e42021-06-08 16:45:41 +0200880 if( ( ret = mbedtls_sha512_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100881 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100882
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100883exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100885
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100886 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000887}
888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
891/*
892 * FIPS-180-2 test vectors
893 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000894static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000895{
896 { "abc" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200897 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000898 { "" }
899};
900
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100901static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000902{
903 3, 112, 1000
904};
905
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200906static const unsigned char sha512_test_sum[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000907{
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200908#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000909 /*
910 * SHA-384 test vectors
911 */
912 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
913 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
914 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
915 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
916 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
917 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
918 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
919 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
920 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
921 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
922 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
923 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
924 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
925 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
926 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
927 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
928 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
929 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200930#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
932 /*
933 * SHA-512 test vectors
934 */
935 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
936 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
937 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
938 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
939 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
940 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
941 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
942 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
943 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
944 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
945 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
946 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
947 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
948 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
949 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
950 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
951 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
952 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
953 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
954 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
955 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
956 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
957 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
958 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
959};
960
Manuel Pégourié-Gonnard74ca84a2020-01-29 09:46:49 +0100961#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200962
Paul Bakker5121ce52009-01-03 21:22:43 +0000963/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 * Checkup routine
965 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000967{
Paul Bakker5b4af392014-06-26 12:09:34 +0200968 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500969 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200970 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000972
Russ Butlerbb83b422016-10-12 17:36:50 -0500973 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
974 if( NULL == buf )
975 {
976 if( verbose != 0 )
977 mbedtls_printf( "Buffer allocation failed\n" );
978
979 return( 1 );
980 }
981
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200983
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100984 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 {
986 j = i % 3;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200987#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000988 k = i < 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200989#else
990 k = 0;
991#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000992
993 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000995
TRodziewicz26371e42021-06-08 16:45:41 +0200996 if( ( ret = mbedtls_sha512_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100997 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000998
999 if( j == 2 )
1000 {
1001 memset( buf, 'a', buflen = 1000 );
1002
1003 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001004 {
TRodziewicz26371e42021-06-08 16:45:41 +02001005 ret = mbedtls_sha512_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001006 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001007 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001008 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001009 }
1010 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001011 {
TRodziewicz26371e42021-06-08 16:45:41 +02001012 ret = mbedtls_sha512_update( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001013 sha512_test_buflen[j] );
1014 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001015 goto fail;
1016 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001017
TRodziewicz26371e42021-06-08 16:45:41 +02001018 if( ( ret = mbedtls_sha512_finish( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001019 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
Paul Bakker9e36f042013-06-30 14:34:05 +02001021 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001022 {
1023 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001024 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +01001025 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001026
1027 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001029 }
1030
1031 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001033
Andres Amaya Garcia614c6892017-05-02 12:07:26 +01001034 goto exit;
1035
1036fail:
1037 if( verbose != 0 )
1038 mbedtls_printf( "failed\n" );
1039
Paul Bakker5b4af392014-06-26 12:09:34 +02001040exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -05001042 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +02001043
1044 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001045}
1046
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +01001047#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +01001048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051#endif /* MBEDTLS_SHA512_C */