blob: 104fa80983cb5f198846ce6b6973b8e708deec47 [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 Yu6b00f5a2023-05-04 16:30:21 +080065
66# ifdef __ARM_NEON
67# include <arm_neon.h>
68# else
69# error "Target does not support NEON instructions"
70# endif
71
Dave Rodgmandb6ab242023-03-14 16:03:57 +000072# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080073# if defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080074# if __clang_major__ < 4
75# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080076# endif
Jerry Yu08933d32023-04-27 18:28:00 +080077# pragma clang attribute push (__attribute__((target("crypto,sha2"))), apply_to=function)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080078# define MBEDTLS_POP_TARGET_PRAGMA
79# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +000080 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
81 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +080082 */
83# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080084# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
85# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080086# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080087# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080088# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080089# endif
90# else
91# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
92# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080093# endif
94/* *INDENT-ON* */
Jerry Yu08933d32023-04-27 18:28:00 +080095
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000096# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000097# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
98# if defined(__unix__)
99# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100100/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000101# include <sys/auxv.h>
102# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100103/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000104# include <signal.h>
105# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000106# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000107#elif defined(_M_ARM64)
108# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000110# include <arm64_neon.h>
111# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000112#else
113# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
114# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
115#endif
116
117#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
118/*
119 * Capability detection code comes early, so we can disable
120 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
121 */
122#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100123static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000124{
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000126}
127#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100128static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000129{
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000131}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000132#elif defined(_M_ARM64)
133#define WIN32_LEAN_AND_MEAN
134#include <Windows.h>
135#include <processthreadsapi.h>
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000138{
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
140 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000141}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000142#elif defined(__unix__) && defined(SIG_SETMASK)
143/* Detection with SIGILL, setjmp() and longjmp() */
144#include <signal.h>
145#include <setjmp.h>
146
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000147static jmp_buf return_from_sigill;
148
149/*
150 * A64 SHA256 support detection via SIGILL
151 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100152static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000153{
154 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000156}
157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000159{
160 struct sigaction old_action, new_action;
161
162 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 if (sigprocmask(0, NULL, &old_mask)) {
164 return 0;
165 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000166
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000168 new_action.sa_flags = 0;
169 new_action.sa_handler = sigill_handler;
170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000172
173 static int ret = 0;
174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000176 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000178 ret = 1;
179 }
180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 sigaction(SIGILL, &old_action, NULL);
182 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000183
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000185}
186#else
187#warning "No mechanism to detect A64_CRYPTO found, using C code only"
188#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
189#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
190
191#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
192
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200193#if !defined(MBEDTLS_SHA256_ALT)
194
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000195#define SHA256_BLOCK_SIZE 64
196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200198{
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200200}
201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200203{
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200205 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200209}
210
Gilles Peskine449bd832023-01-11 14:50:10 +0100211void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
212 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200213{
214 *dst = *src;
215}
216
Paul Bakker5121ce52009-01-03 21:22:43 +0000217/*
218 * SHA-256 context setup
219 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100220int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000221{
Valerio Settia3f99592022-12-14 10:56:54 +0100222#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100224 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 }
Valerio Settia3f99592022-12-14 10:56:54 +0100226#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100228 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 }
Valerio Settia3f99592022-12-14 10:56:54 +0100230#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100232 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200234#endif
235
Paul Bakker5121ce52009-01-03 21:22:43 +0000236 ctx->total[0] = 0;
237 ctx->total[1] = 0;
238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100240#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000241 ctx->state[0] = 0x6A09E667;
242 ctx->state[1] = 0xBB67AE85;
243 ctx->state[2] = 0x3C6EF372;
244 ctx->state[3] = 0xA54FF53A;
245 ctx->state[4] = 0x510E527F;
246 ctx->state[5] = 0x9B05688C;
247 ctx->state[6] = 0x1F83D9AB;
248 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100249#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200251#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000252 ctx->state[0] = 0xC1059ED8;
253 ctx->state[1] = 0x367CD507;
254 ctx->state[2] = 0x3070DD17;
255 ctx->state[3] = 0xF70E5939;
256 ctx->state[4] = 0xFFC00B31;
257 ctx->state[5] = 0x68581511;
258 ctx->state[6] = 0x64F98FA7;
259 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200260#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000261 }
262
Valerio Settia3f99592022-12-14 10:56:54 +0100263#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000264 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100265#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100266
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000268}
269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200271static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000272{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200273 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
274 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
275 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
276 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
277 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
278 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
279 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
280 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
281 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
282 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
283 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
284 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
285 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
286 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
287 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
288 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
289};
Paul Bakker5121ce52009-01-03 21:22:43 +0000290
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000291#endif
292
293#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
294 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
295
296#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
297# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
298# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
299#endif
300
301static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000303{
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
305 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000306
307 size_t processed = 0;
308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000310 len >= SHA256_BLOCK_SIZE;
311 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 msg += SHA256_BLOCK_SIZE,
313 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000314 uint32x4_t tmp, abcd_prev;
315
316 uint32x4_t abcd_orig = abcd;
317 uint32x4_t efgh_orig = efgh;
318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
320 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
321 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
322 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000323
324#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
325 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
327 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
328 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
329 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000330#endif
331
332 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
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 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
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 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
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
350 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000352 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
354 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000357 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
359 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000360 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
362 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000363
364 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
366 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000367 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
369 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000370
371 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
373 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000374 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
376 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000377
378 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
380 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000381 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
383 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000384 }
385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 abcd = vaddq_u32(abcd, abcd_orig);
387 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000388 }
389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 vst1q_u32(&ctx->state[0], abcd);
391 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000394}
395
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100396#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
397/*
398 * This function is for internal use only if we are building both C and A64
399 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
400 */
401static
402#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100403int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
404 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000405{
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
407 SHA256_BLOCK_SIZE) ==
408 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000409}
410
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100411#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
412
Jerry Yu92fc5382023-02-16 11:17:11 +0800413#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800414#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800415#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800416#elif defined(__GNUC__)
417#pragma GCC pop_options
418#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800419#undef MBEDTLS_POP_TARGET_PRAGMA
420#endif
421
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000422#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
423#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
424#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
425#endif
426
427
428#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
429 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
430
Gilles Peskine449bd832023-01-11 14:50:10 +0100431#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
432#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Gilles Peskine449bd832023-01-11 14:50:10 +0100434#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
435#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
438#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
441#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200443#define R(t) \
444 ( \
445 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
446 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100447 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200450 do \
451 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
453 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200454 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100457#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
458/*
459 * This function is for internal use only if we are building both C and A64
460 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
461 */
462static
463#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100464int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
465 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200466{
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200468 uint32_t temp1, temp2, W[64];
469 uint32_t A[8];
470 } local;
471
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200472 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200475 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200477
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200478#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 for (i = 0; i < 64; i++) {
480 if (i < 16) {
481 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
482 } else {
483 R(i);
484 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
487 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200488
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200489 local.temp1 = local.A[7]; local.A[7] = local.A[6];
490 local.A[6] = local.A[5]; local.A[5] = local.A[4];
491 local.A[4] = local.A[3]; local.A[3] = local.A[2];
492 local.A[2] = local.A[1]; local.A[1] = local.A[0];
493 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200494 }
495#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 for (i = 0; i < 16; i++) {
497 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200498 }
499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 for (i = 0; i < 16; i += 8) {
501 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
502 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
503 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
504 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
505 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
506 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
507 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
508 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
509 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
510 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
511 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
512 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
513 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
514 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
515 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
516 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
517 }
518
519 for (i = 16; i < 64; i += 8) {
520 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
521 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
522 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
523 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
524 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
525 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
526 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
527 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
528 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
529 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
530 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
531 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
532 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
533 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
534 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
535 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200536 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200537#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200540 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100542
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200543 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000547}
Jaeden Amero041039f2018-02-19 15:28:08 +0000548
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000549#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
550
551
552#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
553
554static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000556{
557 size_t processed = 0;
558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 while (len >= SHA256_BLOCK_SIZE) {
560 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
561 return 0;
562 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000563
564 data += SHA256_BLOCK_SIZE;
565 len -= SHA256_BLOCK_SIZE;
566
567 processed += SHA256_BLOCK_SIZE;
568 }
569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000571}
572
573#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
574
575
576#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000579{
580 static int done = 0;
581 static int supported = 0;
582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000584 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000585 done = 1;
586 }
587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000589}
590
Gilles Peskine449bd832023-01-11 14:50:10 +0100591static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
592 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000593{
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 if (mbedtls_a64_crypto_sha256_has_support()) {
595 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
596 } else {
597 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
598 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000599}
600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
602 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000603{
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 if (mbedtls_a64_crypto_sha256_has_support()) {
605 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
606 } else {
607 return mbedtls_internal_sha256_process_c(ctx, data);
608 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000609}
610
611#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
612
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614/*
615 * SHA-256 process buffer
616 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100617int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
618 const unsigned char *input,
619 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000620{
Janos Follath24eed8d2019-11-22 13:21:35 +0000621 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000622 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000623 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 if (ilen == 0) {
626 return 0;
627 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000628
629 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000630 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000631
Paul Bakker5c2364c2012-10-01 14:41:15 +0000632 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 ctx->total[0] &= 0xFFFFFFFF;
634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 if (left && ilen >= fill) {
640 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
643 return ret;
644 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100645
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 input += fill;
647 ilen -= fill;
648 left = 0;
649 }
650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000652 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 mbedtls_internal_sha256_process_many(ctx, input, ilen);
654 if (processed < SHA256_BLOCK_SIZE) {
655 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
656 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100657
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000658 input += processed;
659 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 }
661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 if (ilen > 0) {
663 memcpy((void *) (ctx->buffer + left), input, ilen);
664 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000667}
668
Paul Bakker5121ce52009-01-03 21:22:43 +0000669/*
670 * SHA-256 final digest
671 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100672int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
673 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000674{
Janos Follath24eed8d2019-11-22 13:21:35 +0000675 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200676 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000677 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200679 /*
680 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
681 */
682 used = ctx->total[0] & 0x3F;
683
684 ctx->buffer[used++] = 0x80;
685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200687 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 memset(ctx->buffer + used, 0, 56 - used);
689 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200690 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
694 return ret;
695 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200698 }
699
700 /*
701 * Add message length
702 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 high = (ctx->total[0] >> 29)
704 | (ctx->total[1] << 3);
705 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
708 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
711 return ret;
712 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100713
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200714 /*
715 * Output final state
716 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
718 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
719 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
720 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
721 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
722 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
723 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
David Horstmann687262c2022-10-06 17:54:57 +0100725 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200726#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100727 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200728#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 if (!truncated) {
730 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
731 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100732
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000734}
735
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200737
Paul Bakker5121ce52009-01-03 21:22:43 +0000738/*
739 * output = SHA-256( input buffer )
740 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100741int mbedtls_sha256(const unsigned char *input,
742 size_t ilen,
743 unsigned char *output,
744 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000745{
Janos Follath24eed8d2019-11-22 13:21:35 +0000746 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Valerio Settia3f99592022-12-14 10:56:54 +0100749#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100751 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 }
Valerio Settia3f99592022-12-14 10:56:54 +0100753#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100755 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
Valerio Settia3f99592022-12-14 10:56:54 +0100757#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100759 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200761#endif
762
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100766 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100770 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100774 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100776
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100777exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000781}
782
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000784/*
785 * FIPS-180-2 test vectors
786 */
Valerio Settia3f99592022-12-14 10:56:54 +0100787static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000788{
789 { "abc" },
790 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
791 { "" }
792};
793
Valerio Settia3f99592022-12-14 10:56:54 +0100794static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000795{
796 3, 56, 1000
797};
798
Valerio Settia3f99592022-12-14 10:56:54 +0100799typedef const unsigned char (sha_test_sum_t)[32];
800
801/*
802 * SHA-224 test vectors
803 */
804#if defined(MBEDTLS_SHA224_C)
805static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000806{
Paul Bakker5121ce52009-01-03 21:22:43 +0000807 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
808 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
809 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
810 0xE3, 0x6C, 0x9D, 0xA7 },
811 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
812 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
813 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
814 0x52, 0x52, 0x25, 0x25 },
815 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
816 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
817 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100818 0x4E, 0xE7, 0xAD, 0x67 }
819};
820#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000821
Valerio Settia3f99592022-12-14 10:56:54 +0100822/*
823 * SHA-256 test vectors
824 */
825#if defined(MBEDTLS_SHA256_C)
826static sha_test_sum_t sha256_test_sum[] =
827{
Paul Bakker5121ce52009-01-03 21:22:43 +0000828 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
829 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
830 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
831 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
832 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
833 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
834 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
835 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
836 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
837 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
838 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
839 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
840};
Valerio Settia3f99592022-12-14 10:56:54 +0100841#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000842
843/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000844 * Checkup routine
845 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100846static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000847{
Valerio Settia3f99592022-12-14 10:56:54 +0100848 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500849 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200850 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000852
Valerio Settia3f99592022-12-14 10:56:54 +0100853#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100855#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100857#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100859#endif
860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 buf = mbedtls_calloc(1024, sizeof(unsigned char));
862 if (NULL == buf) {
863 if (verbose != 0) {
864 mbedtls_printf("Buffer allocation failed\n");
865 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500866
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500868 }
869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 for (i = 0; i < 3; i++) {
873 if (verbose != 0) {
874 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
875 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100878 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000880
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 if (i == 2) {
882 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 for (int j = 0; j < 1000; j++) {
885 ret = mbedtls_sha256_update(&ctx, buf, buflen);
886 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100887 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100889 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 } else {
892 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
893 sha_test_buflen[i]);
894 if (ret != 0) {
895 goto fail;
896 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100897 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100900 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100902
Paul Bakker5121ce52009-01-03 21:22:43 +0000903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100905 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100906 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100907 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 if (verbose != 0) {
910 mbedtls_printf("passed\n");
911 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000912 }
913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 if (verbose != 0) {
915 mbedtls_printf("\n");
916 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100918 goto exit;
919
920fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 if (verbose != 0) {
922 mbedtls_printf("failed\n");
923 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100924
Paul Bakker5b4af392014-06-26 12:09:34 +0200925exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 mbedtls_sha256_free(&ctx);
927 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200928
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000930}
931
Valerio Settia3f99592022-12-14 10:56:54 +0100932#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100933int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100934{
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100936}
937#endif /* MBEDTLS_SHA256_C */
938
939#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100940int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100941{
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100943}
944#endif /* MBEDTLS_SHA224_C */
945
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000947
Valerio Settia3f99592022-12-14 10:56:54 +0100948#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */