blob: ae1b35ca5e74b981c1d3f6c1939445a960e7f186 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 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-256 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Jerry Yua135dee2023-02-16 16:56:22 +080025#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
Jerry Yu6f86c192023-03-13 11:03:40 +080026 defined(__clang__) && __clang_major__ >= 4
Jerry Yua135dee2023-02-16 16:56:22 +080027/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
28 *
Jerry Yufc2e1282023-02-27 11:16:56 +080029 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
30 * these are normally only enabled by the -march option on the command line.
31 * By defining the macros ourselves we gain access to those declarations without
32 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080033 *
Jerry Yufc2e1282023-02-27 11:16:56 +080034 * `arm_neon.h` could be included by any header file, so we put these defines
35 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080036 */
37#define __ARM_FEATURE_CRYPTO 1
Jerry Yuae129c32023-03-03 15:55:56 +080038/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
39 *
Jerry Yu490bf082023-03-06 15:21:44 +080040 * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
41 * for older compilers.
Jerry Yuae129c32023-03-03 15:55:56 +080042 */
43#define __ARM_FEATURE_SHA2 1
Dave Rodgmandb6ab242023-03-14 16:03:57 +000044#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
Jerry Yu490bf082023-03-06 15:21:44 +080045#endif
Jerry Yua135dee2023-02-16 16:56:22 +080046
Gilles Peskinedb09ef62020-06-03 01:43:33 +020047#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000048
Valerio Settia3f99592022-12-14 10:56:54 +010049#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000050
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000051#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050052#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000053#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000054
Rich Evans00ab4702015-02-06 13:43:58 +000055#include <string.h>
56
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000057#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010058
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000059#if defined(__aarch64__)
Jerry Yu08933d32023-04-27 18:28:00 +080060
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000061# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010062 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Jerry Yu08933d32023-04-27 18:28:00 +080063
Jerry Yu35f2b262023-02-15 11:35:55 +080064/* *INDENT-OFF* */
Jerry Yu08933d32023-04-27 18:28:00 +080065# include <arm_neon.h>
Dave Rodgmandb6ab242023-03-14 16:03:57 +000066# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080067# if defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080068# if __clang_major__ < 4
69# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080070# endif
Jerry Yu08933d32023-04-27 18:28:00 +080071# pragma clang attribute push (__attribute__((target("crypto,sha2"))), apply_to=function)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080072# define MBEDTLS_POP_TARGET_PRAGMA
73# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +000074 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
75 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +080076 */
77# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080078# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
79# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080080# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080081# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080082# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080083# endif
84# else
85# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
86# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080087# endif
88/* *INDENT-ON* */
Jerry Yu08933d32023-04-27 18:28:00 +080089
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000090# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000091# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
92# if defined(__unix__)
93# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010094/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000095# include <sys/auxv.h>
96# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010097/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000098# include <signal.h>
99# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000100# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000101#elif defined(_M_ARM64)
102# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100103 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000104# include <arm64_neon.h>
105# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000106#else
107# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
108# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
109#endif
110
111#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
112/*
113 * Capability detection code comes early, so we can disable
114 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
115 */
116#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100117static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000118{
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000120}
121#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100122static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000123{
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000125}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000126#elif defined(_M_ARM64)
127#define WIN32_LEAN_AND_MEAN
128#include <Windows.h>
129#include <processthreadsapi.h>
130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000132{
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
134 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000135}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000136#elif defined(__unix__) && defined(SIG_SETMASK)
137/* Detection with SIGILL, setjmp() and longjmp() */
138#include <signal.h>
139#include <setjmp.h>
140
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000141static jmp_buf return_from_sigill;
142
143/*
144 * A64 SHA256 support detection via SIGILL
145 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100146static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000147{
148 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000150}
151
Gilles Peskine449bd832023-01-11 14:50:10 +0100152static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000153{
154 struct sigaction old_action, new_action;
155
156 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 if (sigprocmask(0, NULL, &old_mask)) {
158 return 0;
159 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000160
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000162 new_action.sa_flags = 0;
163 new_action.sa_handler = sigill_handler;
164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000166
167 static int ret = 0;
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000170 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000172 ret = 1;
173 }
174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 sigaction(SIGILL, &old_action, NULL);
176 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000177
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000179}
180#else
181#warning "No mechanism to detect A64_CRYPTO found, using C code only"
182#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
183#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
184
185#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
186
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200187#if !defined(MBEDTLS_SHA256_ALT)
188
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000189#define SHA256_BLOCK_SIZE 64
190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200192{
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200194}
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200197{
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200199 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200203}
204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
206 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200207{
208 *dst = *src;
209}
210
Paul Bakker5121ce52009-01-03 21:22:43 +0000211/*
212 * SHA-256 context setup
213 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100214int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000215{
Valerio Settia3f99592022-12-14 10:56:54 +0100216#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100218 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 }
Valerio Settia3f99592022-12-14 10:56:54 +0100220#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100222 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 }
Valerio Settia3f99592022-12-14 10:56:54 +0100224#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100226 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200228#endif
229
Paul Bakker5121ce52009-01-03 21:22:43 +0000230 ctx->total[0] = 0;
231 ctx->total[1] = 0;
232
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100234#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000235 ctx->state[0] = 0x6A09E667;
236 ctx->state[1] = 0xBB67AE85;
237 ctx->state[2] = 0x3C6EF372;
238 ctx->state[3] = 0xA54FF53A;
239 ctx->state[4] = 0x510E527F;
240 ctx->state[5] = 0x9B05688C;
241 ctx->state[6] = 0x1F83D9AB;
242 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100243#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200245#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000246 ctx->state[0] = 0xC1059ED8;
247 ctx->state[1] = 0x367CD507;
248 ctx->state[2] = 0x3070DD17;
249 ctx->state[3] = 0xF70E5939;
250 ctx->state[4] = 0xFFC00B31;
251 ctx->state[5] = 0x68581511;
252 ctx->state[6] = 0x64F98FA7;
253 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200254#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000255 }
256
Valerio Settia3f99592022-12-14 10:56:54 +0100257#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100259#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100260
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000262}
263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200265static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000266{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200267 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
268 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
269 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
270 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
271 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
272 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
273 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
274 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
275 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
276 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
277 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
278 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
279 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
280 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
281 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
282 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
283};
Paul Bakker5121ce52009-01-03 21:22:43 +0000284
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000285#endif
286
287#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
288 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
289
290#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
291# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
292# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
293#endif
294
295static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000297{
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
299 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000300
301 size_t processed = 0;
302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000304 len >= SHA256_BLOCK_SIZE;
305 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 msg += SHA256_BLOCK_SIZE,
307 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000308 uint32x4_t tmp, abcd_prev;
309
310 uint32x4_t abcd_orig = abcd;
311 uint32x4_t efgh_orig = efgh;
312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
314 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
315 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
316 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000317
318#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
319 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
321 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
322 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
323 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000324#endif
325
326 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000328 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
330 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000331
332 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
336 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000337
338 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000340 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
342 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000343
344 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000346 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
348 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000351 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
353 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000354 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
356 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000357
358 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
360 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000361 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
363 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000364
365 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
367 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000368 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
370 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000371
372 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
374 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000375 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
377 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000378 }
379
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 abcd = vaddq_u32(abcd, abcd_orig);
381 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000382 }
383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 vst1q_u32(&ctx->state[0], abcd);
385 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000388}
389
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100390#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
391/*
392 * This function is for internal use only if we are building both C and A64
393 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
394 */
395static
396#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100397int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
398 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000399{
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
401 SHA256_BLOCK_SIZE) ==
402 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000403}
404
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100405#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
406
Jerry Yu92fc5382023-02-16 11:17:11 +0800407#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800408#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800409#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800410#elif defined(__GNUC__)
411#pragma GCC pop_options
412#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800413#undef MBEDTLS_POP_TARGET_PRAGMA
414#endif
415
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000416#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
417#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
418#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
419#endif
420
421
422#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
423 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
426#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
Gilles Peskine449bd832023-01-11 14:50:10 +0100428#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
429#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
Gilles Peskine449bd832023-01-11 14:50:10 +0100431#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
432#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Gilles Peskine449bd832023-01-11 14:50:10 +0100434#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
435#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200437#define R(t) \
438 ( \
439 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
440 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100441 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200444 do \
445 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
447 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200448 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100451#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
452/*
453 * This function is for internal use only if we are building both C and A64
454 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
455 */
456static
457#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100458int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
459 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200460{
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200462 uint32_t temp1, temp2, W[64];
463 uint32_t A[8];
464 } local;
465
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200466 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200469 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200471
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200472#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 for (i = 0; i < 64; i++) {
474 if (i < 16) {
475 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
476 } else {
477 R(i);
478 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
481 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200482
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200483 local.temp1 = local.A[7]; local.A[7] = local.A[6];
484 local.A[6] = local.A[5]; local.A[5] = local.A[4];
485 local.A[4] = local.A[3]; local.A[3] = local.A[2];
486 local.A[2] = local.A[1]; local.A[1] = local.A[0];
487 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200488 }
489#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 for (i = 0; i < 16; i++) {
491 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200492 }
493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 for (i = 0; i < 16; i += 8) {
495 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
496 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
497 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
498 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
499 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
500 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
501 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
502 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
503 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
504 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
505 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
506 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
507 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
508 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
509 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
510 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
511 }
512
513 for (i = 16; i < 64; i += 8) {
514 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
515 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
516 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
517 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
518 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
519 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
520 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
521 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
522 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
523 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
524 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
525 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
526 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
527 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
528 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
529 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200530 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200531#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200534 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100536
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200537 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000541}
Jaeden Amero041039f2018-02-19 15:28:08 +0000542
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000543#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
544
545
546#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
547
548static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000550{
551 size_t processed = 0;
552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 while (len >= SHA256_BLOCK_SIZE) {
554 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
555 return 0;
556 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000557
558 data += SHA256_BLOCK_SIZE;
559 len -= SHA256_BLOCK_SIZE;
560
561 processed += SHA256_BLOCK_SIZE;
562 }
563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000565}
566
567#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
568
569
570#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000573{
574 static int done = 0;
575 static int supported = 0;
576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000578 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000579 done = 1;
580 }
581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000583}
584
Gilles Peskine449bd832023-01-11 14:50:10 +0100585static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
586 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000587{
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 if (mbedtls_a64_crypto_sha256_has_support()) {
589 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
590 } else {
591 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
592 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000593}
594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
596 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000597{
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 if (mbedtls_a64_crypto_sha256_has_support()) {
599 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
600 } else {
601 return mbedtls_internal_sha256_process_c(ctx, data);
602 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000603}
604
605#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
606
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
608/*
609 * SHA-256 process buffer
610 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100611int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
612 const unsigned char *input,
613 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000614{
Janos Follath24eed8d2019-11-22 13:21:35 +0000615 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000616 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000617 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 if (ilen == 0) {
620 return 0;
621 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
623 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000624 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
Paul Bakker5c2364c2012-10-01 14:41:15 +0000626 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 ctx->total[0] &= 0xFFFFFFFF;
628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 if (left && ilen >= fill) {
634 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
637 return ret;
638 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100639
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 input += fill;
641 ilen -= fill;
642 left = 0;
643 }
644
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000646 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 mbedtls_internal_sha256_process_many(ctx, input, ilen);
648 if (processed < SHA256_BLOCK_SIZE) {
649 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
650 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100651
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000652 input += processed;
653 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 }
655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 if (ilen > 0) {
657 memcpy((void *) (ctx->buffer + left), input, ilen);
658 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100659
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661}
662
Paul Bakker5121ce52009-01-03 21:22:43 +0000663/*
664 * SHA-256 final digest
665 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100666int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
667 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000668{
Janos Follath24eed8d2019-11-22 13:21:35 +0000669 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200670 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000671 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000672
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200673 /*
674 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
675 */
676 used = ctx->total[0] & 0x3F;
677
678 ctx->buffer[used++] = 0x80;
679
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200681 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 memset(ctx->buffer + used, 0, 56 - used);
683 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200684 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200686
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
688 return ret;
689 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200690
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200692 }
693
694 /*
695 * Add message length
696 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 high = (ctx->total[0] >> 29)
698 | (ctx->total[1] << 3);
699 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
702 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000703
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
705 return ret;
706 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100707
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200708 /*
709 * Output final state
710 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
712 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
713 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
714 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
715 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
716 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
717 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000718
David Horstmann687262c2022-10-06 17:54:57 +0100719 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200720#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100721 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200722#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 if (!truncated) {
724 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
725 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000728}
729
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200730#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200731
Paul Bakker5121ce52009-01-03 21:22:43 +0000732/*
733 * output = SHA-256( input buffer )
734 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100735int mbedtls_sha256(const unsigned char *input,
736 size_t ilen,
737 unsigned char *output,
738 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000739{
Janos Follath24eed8d2019-11-22 13:21:35 +0000740 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000742
Valerio Settia3f99592022-12-14 10:56:54 +0100743#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100745 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 }
Valerio Settia3f99592022-12-14 10:56:54 +0100747#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100749 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 }
Valerio Settia3f99592022-12-14 10:56:54 +0100751#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100753 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200755#endif
756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100758
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100760 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100762
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100764 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100768 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100770
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100771exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000775}
776
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000778/*
779 * FIPS-180-2 test vectors
780 */
Valerio Settia3f99592022-12-14 10:56:54 +0100781static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000782{
783 { "abc" },
784 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
785 { "" }
786};
787
Valerio Settia3f99592022-12-14 10:56:54 +0100788static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000789{
790 3, 56, 1000
791};
792
Valerio Settia3f99592022-12-14 10:56:54 +0100793typedef const unsigned char (sha_test_sum_t)[32];
794
795/*
796 * SHA-224 test vectors
797 */
798#if defined(MBEDTLS_SHA224_C)
799static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000800{
Paul Bakker5121ce52009-01-03 21:22:43 +0000801 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
802 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
803 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
804 0xE3, 0x6C, 0x9D, 0xA7 },
805 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
806 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
807 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
808 0x52, 0x52, 0x25, 0x25 },
809 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
810 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
811 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100812 0x4E, 0xE7, 0xAD, 0x67 }
813};
814#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000815
Valerio Settia3f99592022-12-14 10:56:54 +0100816/*
817 * SHA-256 test vectors
818 */
819#if defined(MBEDTLS_SHA256_C)
820static sha_test_sum_t sha256_test_sum[] =
821{
Paul Bakker5121ce52009-01-03 21:22:43 +0000822 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
823 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
824 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
825 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
826 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
827 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
828 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
829 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
830 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
831 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
832 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
833 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
834};
Valerio Settia3f99592022-12-14 10:56:54 +0100835#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000836
837/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000838 * Checkup routine
839 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100840static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000841{
Valerio Settia3f99592022-12-14 10:56:54 +0100842 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500843 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200844 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000846
Valerio Settia3f99592022-12-14 10:56:54 +0100847#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100849#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100851#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100853#endif
854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 buf = mbedtls_calloc(1024, sizeof(unsigned char));
856 if (NULL == buf) {
857 if (verbose != 0) {
858 mbedtls_printf("Buffer allocation failed\n");
859 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500862 }
863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 for (i = 0; i < 3; i++) {
867 if (verbose != 0) {
868 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
869 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000870
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100872 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 if (i == 2) {
876 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 for (int j = 0; j < 1000; j++) {
879 ret = mbedtls_sha256_update(&ctx, buf, buflen);
880 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100881 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100883 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100884
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 } else {
886 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
887 sha_test_buflen[i]);
888 if (ret != 0) {
889 goto fail;
890 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100891 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100894 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100896
Paul Bakker5121ce52009-01-03 21:22:43 +0000897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100899 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100900 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100901 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 if (verbose != 0) {
904 mbedtls_printf("passed\n");
905 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 }
907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 if (verbose != 0) {
909 mbedtls_printf("\n");
910 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000911
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100912 goto exit;
913
914fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 if (verbose != 0) {
916 mbedtls_printf("failed\n");
917 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100918
Paul Bakker5b4af392014-06-26 12:09:34 +0200919exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 mbedtls_sha256_free(&ctx);
921 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200922
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000924}
925
Valerio Settia3f99592022-12-14 10:56:54 +0100926#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100927int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100928{
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100930}
931#endif /* MBEDTLS_SHA256_C */
932
933#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100934int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100935{
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100937}
938#endif /* MBEDTLS_SHA224_C */
939
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
Valerio Settia3f99592022-12-14 10:56:54 +0100942#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */