blob: 5375255a8d7ddbc33792927cdb0eef1c5eab1cf4 [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 Yub1d06bb2023-05-05 14:05:07 +080073# if defined(__ARMCOMPILER_VERSION)
74# if __ARMCOMPILER_VERSION <= 6090000
75# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
76# endif
77# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
78# define MBEDTLS_POP_TARGET_PRAGMA
79# elif defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080080# if __clang_major__ < 4
81# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080082# endif
Jerry Yub1d06bb2023-05-05 14:05:07 +080083# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080084# define MBEDTLS_POP_TARGET_PRAGMA
85# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +000086 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
87 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +080088 */
89# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080090# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
91# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080092# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080093# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080094# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080095# endif
96# else
97# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
98# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080099# endif
100/* *INDENT-ON* */
Jerry Yu08933d32023-04-27 18:28:00 +0800101
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000102# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000103# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
104# if defined(__unix__)
105# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100106/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000107# include <sys/auxv.h>
108# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100109/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000110# include <signal.h>
111# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000112# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000113#elif defined(_M_ARM64)
114# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000116# include <arm64_neon.h>
117# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000118#else
119# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
120# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
121#endif
122
123#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
124/*
125 * Capability detection code comes early, so we can disable
126 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
127 */
128#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100129static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000130{
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000132}
133#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100134static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000135{
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000137}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000138#elif defined(_M_ARM64)
139#define WIN32_LEAN_AND_MEAN
140#include <Windows.h>
141#include <processthreadsapi.h>
142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000144{
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
146 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000147}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000148#elif defined(__unix__) && defined(SIG_SETMASK)
149/* Detection with SIGILL, setjmp() and longjmp() */
150#include <signal.h>
151#include <setjmp.h>
152
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000153static jmp_buf return_from_sigill;
154
155/*
156 * A64 SHA256 support detection via SIGILL
157 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100158static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000159{
160 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000162}
163
Gilles Peskine449bd832023-01-11 14:50:10 +0100164static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000165{
166 struct sigaction old_action, new_action;
167
168 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 if (sigprocmask(0, NULL, &old_mask)) {
170 return 0;
171 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000174 new_action.sa_flags = 0;
175 new_action.sa_handler = sigill_handler;
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000178
179 static int ret = 0;
180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000182 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000184 ret = 1;
185 }
186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 sigaction(SIGILL, &old_action, NULL);
188 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000191}
192#else
193#warning "No mechanism to detect A64_CRYPTO found, using C code only"
194#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
195#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
196
197#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
198
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200199#if !defined(MBEDTLS_SHA256_ALT)
200
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000201#define SHA256_BLOCK_SIZE 64
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200204{
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200206}
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200209{
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200211 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200215}
216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
218 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200219{
220 *dst = *src;
221}
222
Paul Bakker5121ce52009-01-03 21:22:43 +0000223/*
224 * SHA-256 context setup
225 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100226int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000227{
Valerio Settia3f99592022-12-14 10:56:54 +0100228#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100230 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 }
Valerio Settia3f99592022-12-14 10:56:54 +0100232#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100234 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 }
Valerio Settia3f99592022-12-14 10:56:54 +0100236#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100238 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200240#endif
241
Paul Bakker5121ce52009-01-03 21:22:43 +0000242 ctx->total[0] = 0;
243 ctx->total[1] = 0;
244
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100246#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000247 ctx->state[0] = 0x6A09E667;
248 ctx->state[1] = 0xBB67AE85;
249 ctx->state[2] = 0x3C6EF372;
250 ctx->state[3] = 0xA54FF53A;
251 ctx->state[4] = 0x510E527F;
252 ctx->state[5] = 0x9B05688C;
253 ctx->state[6] = 0x1F83D9AB;
254 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100255#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200257#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 ctx->state[0] = 0xC1059ED8;
259 ctx->state[1] = 0x367CD507;
260 ctx->state[2] = 0x3070DD17;
261 ctx->state[3] = 0xF70E5939;
262 ctx->state[4] = 0xFFC00B31;
263 ctx->state[5] = 0x68581511;
264 ctx->state[6] = 0x64F98FA7;
265 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200266#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 }
268
Valerio Settia3f99592022-12-14 10:56:54 +0100269#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100271#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100272
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000274}
275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200277static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000278{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200279 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
280 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
281 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
282 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
283 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
284 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
285 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
286 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
287 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
288 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
289 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
290 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
291 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
292 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
293 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
294 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
295};
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000297#endif
298
299#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
300 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
301
302#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
303# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
304# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
305#endif
306
307static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000309{
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
311 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000312
313 size_t processed = 0;
314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000316 len >= SHA256_BLOCK_SIZE;
317 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 msg += SHA256_BLOCK_SIZE,
319 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000320 uint32x4_t tmp, abcd_prev;
321
322 uint32x4_t abcd_orig = abcd;
323 uint32x4_t efgh_orig = efgh;
324
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
326 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
327 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
328 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000329
330#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
331 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
333 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
334 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
335 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000336#endif
337
338 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
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 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
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 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
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
356 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000358 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
360 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000363 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
365 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000366 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
368 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000369
370 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
372 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000373 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
375 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000376
377 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
379 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000380 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
382 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000383
384 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
386 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000387 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
389 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000390 }
391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 abcd = vaddq_u32(abcd, abcd_orig);
393 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000394 }
395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 vst1q_u32(&ctx->state[0], abcd);
397 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000400}
401
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100402#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
403/*
404 * This function is for internal use only if we are building both C and A64
405 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
406 */
407static
408#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100409int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
410 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000411{
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
413 SHA256_BLOCK_SIZE) ==
414 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000415}
416
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100417#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
418
Jerry Yu92fc5382023-02-16 11:17:11 +0800419#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800420#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800421#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800422#elif defined(__GNUC__)
423#pragma GCC pop_options
424#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800425#undef MBEDTLS_POP_TARGET_PRAGMA
426#endif
427
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000428#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
429#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
430#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
431#endif
432
433
434#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
435 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
438#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
441#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
444#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
447#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200449#define R(t) \
450 ( \
451 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
452 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100453 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200456 do \
457 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
459 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200460 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100463#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
464/*
465 * This function is for internal use only if we are building both C and A64
466 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
467 */
468static
469#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100470int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
471 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200472{
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200474 uint32_t temp1, temp2, W[64];
475 uint32_t A[8];
476 } local;
477
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200478 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200481 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200483
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200484#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 for (i = 0; i < 64; i++) {
486 if (i < 16) {
487 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
488 } else {
489 R(i);
490 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
493 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200494
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200495 local.temp1 = local.A[7]; local.A[7] = local.A[6];
496 local.A[6] = local.A[5]; local.A[5] = local.A[4];
497 local.A[4] = local.A[3]; local.A[3] = local.A[2];
498 local.A[2] = local.A[1]; local.A[1] = local.A[0];
499 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200500 }
501#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 for (i = 0; i < 16; i++) {
503 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200504 }
505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 for (i = 0; i < 16; i += 8) {
507 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
508 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
509 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
510 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
511 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
512 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
513 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
514 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
515 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
516 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
517 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
518 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
519 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
520 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
521 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
522 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
523 }
524
525 for (i = 16; i < 64; i += 8) {
526 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
527 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
528 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
529 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
530 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
531 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
532 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
533 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
534 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
535 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
536 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
537 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
538 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
539 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
540 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
541 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200542 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200543#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200546 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100548
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200549 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000553}
Jaeden Amero041039f2018-02-19 15:28:08 +0000554
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000555#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
556
557
558#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
559
560static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000562{
563 size_t processed = 0;
564
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 while (len >= SHA256_BLOCK_SIZE) {
566 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
567 return 0;
568 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000569
570 data += SHA256_BLOCK_SIZE;
571 len -= SHA256_BLOCK_SIZE;
572
573 processed += SHA256_BLOCK_SIZE;
574 }
575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000577}
578
579#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
580
581
582#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000585{
586 static int done = 0;
587 static int supported = 0;
588
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000590 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000591 done = 1;
592 }
593
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000595}
596
Gilles Peskine449bd832023-01-11 14:50:10 +0100597static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
598 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000599{
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 if (mbedtls_a64_crypto_sha256_has_support()) {
601 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
602 } else {
603 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
604 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000605}
606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
608 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000609{
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 if (mbedtls_a64_crypto_sha256_has_support()) {
611 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
612 } else {
613 return mbedtls_internal_sha256_process_c(ctx, data);
614 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000615}
616
617#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
618
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
620/*
621 * SHA-256 process buffer
622 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100623int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
624 const unsigned char *input,
625 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000626{
Janos Follath24eed8d2019-11-22 13:21:35 +0000627 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000628 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000629 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 if (ilen == 0) {
632 return 0;
633 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000636 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Paul Bakker5c2364c2012-10-01 14:41:15 +0000638 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000639 ctx->total[0] &= 0xFFFFFFFF;
640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000642 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 if (left && ilen >= fill) {
646 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
649 return ret;
650 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100651
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 input += fill;
653 ilen -= fill;
654 left = 0;
655 }
656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000658 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 mbedtls_internal_sha256_process_many(ctx, input, ilen);
660 if (processed < SHA256_BLOCK_SIZE) {
661 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
662 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100663
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000664 input += processed;
665 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 }
667
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 if (ilen > 0) {
669 memcpy((void *) (ctx->buffer + left), input, ilen);
670 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000673}
674
Paul Bakker5121ce52009-01-03 21:22:43 +0000675/*
676 * SHA-256 final digest
677 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100678int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
679 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000680{
Janos Follath24eed8d2019-11-22 13:21:35 +0000681 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200682 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000683 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200685 /*
686 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
687 */
688 used = ctx->total[0] & 0x3F;
689
690 ctx->buffer[used++] = 0x80;
691
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200693 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 memset(ctx->buffer + used, 0, 56 - used);
695 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200696 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100700 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200702
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200704 }
705
706 /*
707 * Add message length
708 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 high = (ctx->total[0] >> 29)
710 | (ctx->total[1] << 3);
711 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
714 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100717 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100719
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200720 /*
721 * Output final state
722 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
724 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
725 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
726 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
727 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
728 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
729 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
David Horstmann687262c2022-10-06 17:54:57 +0100731 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200732#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100733 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200734#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 if (!truncated) {
736 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
737 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100738
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100739 ret = 0;
740
741exit:
742 mbedtls_sha256_free(ctx);
743 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000744}
745
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200746#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200747
Paul Bakker5121ce52009-01-03 21:22:43 +0000748/*
749 * output = SHA-256( input buffer )
750 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100751int mbedtls_sha256(const unsigned char *input,
752 size_t ilen,
753 unsigned char *output,
754 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000755{
Janos Follath24eed8d2019-11-22 13:21:35 +0000756 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200757 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
Valerio Settia3f99592022-12-14 10:56:54 +0100759#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100761 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 }
Valerio Settia3f99592022-12-14 10:56:54 +0100763#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100765 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 }
Valerio Settia3f99592022-12-14 10:56:54 +0100767#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100769 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200771#endif
772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100776 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100780 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100782
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100784 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100786
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100787exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000791}
792
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000794/*
795 * FIPS-180-2 test vectors
796 */
Valerio Settia3f99592022-12-14 10:56:54 +0100797static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000798{
799 { "abc" },
800 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
801 { "" }
802};
803
Valerio Settia3f99592022-12-14 10:56:54 +0100804static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000805{
806 3, 56, 1000
807};
808
Valerio Settia3f99592022-12-14 10:56:54 +0100809typedef const unsigned char (sha_test_sum_t)[32];
810
811/*
812 * SHA-224 test vectors
813 */
814#if defined(MBEDTLS_SHA224_C)
815static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000816{
Paul Bakker5121ce52009-01-03 21:22:43 +0000817 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
818 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
819 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
820 0xE3, 0x6C, 0x9D, 0xA7 },
821 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
822 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
823 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
824 0x52, 0x52, 0x25, 0x25 },
825 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
826 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
827 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100828 0x4E, 0xE7, 0xAD, 0x67 }
829};
830#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000831
Valerio Settia3f99592022-12-14 10:56:54 +0100832/*
833 * SHA-256 test vectors
834 */
835#if defined(MBEDTLS_SHA256_C)
836static sha_test_sum_t sha256_test_sum[] =
837{
Paul Bakker5121ce52009-01-03 21:22:43 +0000838 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
839 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
840 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
841 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
842 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
843 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
844 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
845 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
846 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
847 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
848 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
849 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
850};
Valerio Settia3f99592022-12-14 10:56:54 +0100851#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000852
853/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000854 * Checkup routine
855 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100856static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000857{
Valerio Settia3f99592022-12-14 10:56:54 +0100858 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500859 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200860 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
Valerio Settia3f99592022-12-14 10:56:54 +0100863#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100865#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100867#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100869#endif
870
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 buf = mbedtls_calloc(1024, sizeof(unsigned char));
872 if (NULL == buf) {
873 if (verbose != 0) {
874 mbedtls_printf("Buffer allocation failed\n");
875 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500878 }
879
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 for (i = 0; i < 3; i++) {
883 if (verbose != 0) {
884 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
885 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100888 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 if (i == 2) {
892 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 for (int j = 0; j < 1000; j++) {
895 ret = mbedtls_sha256_update(&ctx, buf, buflen);
896 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100897 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100899 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 } else {
902 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
903 sha_test_buflen[i]);
904 if (ret != 0) {
905 goto fail;
906 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100907 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100910 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100912
Paul Bakker5121ce52009-01-03 21:22:43 +0000913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100915 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100916 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100917 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if (verbose != 0) {
920 mbedtls_printf("passed\n");
921 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000922 }
923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 if (verbose != 0) {
925 mbedtls_printf("\n");
926 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000927
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100928 goto exit;
929
930fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 if (verbose != 0) {
932 mbedtls_printf("failed\n");
933 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100934
Paul Bakker5b4af392014-06-26 12:09:34 +0200935exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 mbedtls_sha256_free(&ctx);
937 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200938
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000940}
941
Valerio Settia3f99592022-12-14 10:56:54 +0100942#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100943int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100944{
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100946}
947#endif /* MBEDTLS_SHA256_C */
948
949#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100950int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100951{
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100953}
954#endif /* MBEDTLS_SHA224_C */
955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000957
Valerio Settia3f99592022-12-14 10:56:54 +0100958#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */