blob: 29645b06eac211ecefd24138e861054f67507667 [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
Jerry Yub28d55b2023-03-14 10:36:47 +080044#define MBEDTLS_NEED_TARGET_OPTIONS
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__)
60# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010061 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080062/* *INDENT-OFF* */
Jerry Yub28d55b2023-03-14 10:36:47 +080063# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_NEED_TARGET_OPTIONS)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080064# if defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080065# if __clang_major__ < 4
66# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080067# endif
68# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
69# define MBEDTLS_POP_TARGET_PRAGMA
70# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +000071 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
72 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +080073 */
74# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080075# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
76# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080077# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080078# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080079# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080080# endif
81# else
82# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
83# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080084# endif
85/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000086# include <arm_neon.h>
87# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000088# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
89# if defined(__unix__)
90# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010091/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000092# include <sys/auxv.h>
93# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010094/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000095# include <signal.h>
96# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000097# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000098#elif defined(_M_ARM64)
99# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000101# include <arm64_neon.h>
102# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000103#else
104# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
105# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
106#endif
107
108#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
109/*
110 * Capability detection code comes early, so we can disable
111 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
112 */
113#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100114static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000115{
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000117}
118#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100119static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000120{
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000122}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000123#elif defined(_M_ARM64)
124#define WIN32_LEAN_AND_MEAN
125#include <Windows.h>
126#include <processthreadsapi.h>
127
Gilles Peskine449bd832023-01-11 14:50:10 +0100128static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000129{
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
131 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000132}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000133#elif defined(__unix__) && defined(SIG_SETMASK)
134/* Detection with SIGILL, setjmp() and longjmp() */
135#include <signal.h>
136#include <setjmp.h>
137
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000138static jmp_buf return_from_sigill;
139
140/*
141 * A64 SHA256 support detection via SIGILL
142 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100143static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000144{
145 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000147}
148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000150{
151 struct sigaction old_action, new_action;
152
153 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 if (sigprocmask(0, NULL, &old_mask)) {
155 return 0;
156 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000159 new_action.sa_flags = 0;
160 new_action.sa_handler = sigill_handler;
161
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000163
164 static int ret = 0;
165
Gilles Peskine449bd832023-01-11 14:50:10 +0100166 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000167 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000169 ret = 1;
170 }
171
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 sigaction(SIGILL, &old_action, NULL);
173 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000176}
177#else
178#warning "No mechanism to detect A64_CRYPTO found, using C code only"
179#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
180#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
181
182#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
183
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200184#if !defined(MBEDTLS_SHA256_ALT)
185
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000186#define SHA256_BLOCK_SIZE 64
187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200189{
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200191}
192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200194{
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200196 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200200}
201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
203 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200204{
205 *dst = *src;
206}
207
Paul Bakker5121ce52009-01-03 21:22:43 +0000208/*
209 * SHA-256 context setup
210 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100211int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000212{
Valerio Settia3f99592022-12-14 10:56:54 +0100213#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100215 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100216 }
Valerio Settia3f99592022-12-14 10:56:54 +0100217#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100219 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 }
Valerio Settia3f99592022-12-14 10:56:54 +0100221#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100223 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200225#endif
226
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 ctx->total[0] = 0;
228 ctx->total[1] = 0;
229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100231#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000232 ctx->state[0] = 0x6A09E667;
233 ctx->state[1] = 0xBB67AE85;
234 ctx->state[2] = 0x3C6EF372;
235 ctx->state[3] = 0xA54FF53A;
236 ctx->state[4] = 0x510E527F;
237 ctx->state[5] = 0x9B05688C;
238 ctx->state[6] = 0x1F83D9AB;
239 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100240#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200242#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000243 ctx->state[0] = 0xC1059ED8;
244 ctx->state[1] = 0x367CD507;
245 ctx->state[2] = 0x3070DD17;
246 ctx->state[3] = 0xF70E5939;
247 ctx->state[4] = 0xFFC00B31;
248 ctx->state[5] = 0x68581511;
249 ctx->state[6] = 0x64F98FA7;
250 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200251#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000252 }
253
Valerio Settia3f99592022-12-14 10:56:54 +0100254#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000255 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100256#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100257
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000259}
260
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200261#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200262static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000263{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200264 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
265 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
266 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
267 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
268 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
269 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
270 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
271 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
272 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
273 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
274 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
275 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
276 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
277 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
278 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
279 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
280};
Paul Bakker5121ce52009-01-03 21:22:43 +0000281
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000282#endif
283
284#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
285 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
286
287#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
288# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
289# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
290#endif
291
292static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000294{
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
296 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000297
298 size_t processed = 0;
299
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000301 len >= SHA256_BLOCK_SIZE;
302 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 msg += SHA256_BLOCK_SIZE,
304 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000305 uint32x4_t tmp, abcd_prev;
306
307 uint32x4_t abcd_orig = abcd;
308 uint32x4_t efgh_orig = efgh;
309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
311 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
312 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
313 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000314
315#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
316 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
318 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
319 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
320 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000321#endif
322
323 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000325 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
327 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000328
329 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000331 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
333 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334
335 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000337 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
339 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000340
341 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000343 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
345 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000348 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
350 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000351 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
353 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000354
355 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
357 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
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
362 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
364 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000365 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
367 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000368
369 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
371 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000372 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
374 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000375 }
376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 abcd = vaddq_u32(abcd, abcd_orig);
378 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000379 }
380
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 vst1q_u32(&ctx->state[0], abcd);
382 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000385}
386
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100387#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
388/*
389 * This function is for internal use only if we are building both C and A64
390 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
391 */
392static
393#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100394int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
395 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000396{
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
398 SHA256_BLOCK_SIZE) ==
399 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000400}
401
Jerry Yu92fc5382023-02-16 11:17:11 +0800402#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800403#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800404#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800405#elif defined(__GNUC__)
406#pragma GCC pop_options
407#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800408#undef MBEDTLS_POP_TARGET_PRAGMA
409#endif
410
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000411#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
412
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000413#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
414#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
415#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
416#endif
417
418
419#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
420 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
423#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
426#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
Gilles Peskine449bd832023-01-11 14:50:10 +0100428#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
429#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
Gilles Peskine449bd832023-01-11 14:50:10 +0100431#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
432#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200434#define R(t) \
435 ( \
436 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
437 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100438 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200441 do \
442 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
444 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200445 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100448#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
449/*
450 * This function is for internal use only if we are building both C and A64
451 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
452 */
453static
454#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100455int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
456 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200457{
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200459 uint32_t temp1, temp2, W[64];
460 uint32_t A[8];
461 } local;
462
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200463 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200466 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200468
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200469#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 for (i = 0; i < 64; i++) {
471 if (i < 16) {
472 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
473 } else {
474 R(i);
475 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
478 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200479
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200480 local.temp1 = local.A[7]; local.A[7] = local.A[6];
481 local.A[6] = local.A[5]; local.A[5] = local.A[4];
482 local.A[4] = local.A[3]; local.A[3] = local.A[2];
483 local.A[2] = local.A[1]; local.A[1] = local.A[0];
484 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200485 }
486#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 for (i = 0; i < 16; i++) {
488 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200489 }
490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 for (i = 0; i < 16; i += 8) {
492 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+0], K[i+0]);
494 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
495 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
496 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
497 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
498 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
499 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
500 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
501 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
502 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
503 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
504 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
505 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
506 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
507 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
508 }
509
510 for (i = 16; i < 64; i += 8) {
511 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
512 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
513 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
514 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
515 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
516 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
517 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
518 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
519 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
520 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
521 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
522 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
523 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
524 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
525 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
526 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200527 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200528#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200531 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100533
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200534 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000538}
Jaeden Amero041039f2018-02-19 15:28:08 +0000539
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000540#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
541
542
543#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
544
545static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000547{
548 size_t processed = 0;
549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 while (len >= SHA256_BLOCK_SIZE) {
551 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
552 return 0;
553 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000554
555 data += SHA256_BLOCK_SIZE;
556 len -= SHA256_BLOCK_SIZE;
557
558 processed += SHA256_BLOCK_SIZE;
559 }
560
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000562}
563
564#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
565
566
567#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000570{
571 static int done = 0;
572 static int supported = 0;
573
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000575 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000576 done = 1;
577 }
578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000580}
581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
583 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000584{
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 if (mbedtls_a64_crypto_sha256_has_support()) {
586 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
587 } else {
588 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
589 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000590}
591
Gilles Peskine449bd832023-01-11 14:50:10 +0100592int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
593 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000594{
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 if (mbedtls_a64_crypto_sha256_has_support()) {
596 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
597 } else {
598 return mbedtls_internal_sha256_process_c(ctx, data);
599 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000600}
601
602#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
603
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605/*
606 * SHA-256 process buffer
607 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100608int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
609 const unsigned char *input,
610 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000611{
Janos Follath24eed8d2019-11-22 13:21:35 +0000612 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000613 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000614 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 if (ilen == 0) {
617 return 0;
618 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
620 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000621 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
Paul Bakker5c2364c2012-10-01 14:41:15 +0000623 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 ctx->total[0] &= 0xFFFFFFFF;
625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if (left && ilen >= fill) {
631 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
634 return ret;
635 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100636
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 input += fill;
638 ilen -= fill;
639 left = 0;
640 }
641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000643 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 mbedtls_internal_sha256_process_many(ctx, input, ilen);
645 if (processed < SHA256_BLOCK_SIZE) {
646 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
647 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100648
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000649 input += processed;
650 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 }
652
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 if (ilen > 0) {
654 memcpy((void *) (ctx->buffer + left), input, ilen);
655 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000658}
659
Paul Bakker5121ce52009-01-03 21:22:43 +0000660/*
661 * SHA-256 final digest
662 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100663int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
664 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000665{
Janos Follath24eed8d2019-11-22 13:21:35 +0000666 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200667 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000668 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000669
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200670 /*
671 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
672 */
673 used = ctx->total[0] & 0x3F;
674
675 ctx->buffer[used++] = 0x80;
676
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200678 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 memset(ctx->buffer + used, 0, 56 - used);
680 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200681 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200683
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
685 return ret;
686 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200689 }
690
691 /*
692 * Add message length
693 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 high = (ctx->total[0] >> 29)
695 | (ctx->total[1] << 3);
696 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
699 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
702 return ret;
703 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100704
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200705 /*
706 * Output final state
707 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
709 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
710 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
711 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
712 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
713 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
714 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
David Horstmann687262c2022-10-06 17:54:57 +0100716 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200717#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100718 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200719#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 if (!truncated) {
721 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
722 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000725}
726
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200727#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200728
Paul Bakker5121ce52009-01-03 21:22:43 +0000729/*
730 * output = SHA-256( input buffer )
731 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100732int mbedtls_sha256(const unsigned char *input,
733 size_t ilen,
734 unsigned char *output,
735 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000736{
Janos Follath24eed8d2019-11-22 13:21:35 +0000737 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
Valerio Settia3f99592022-12-14 10:56:54 +0100740#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100742 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 }
Valerio Settia3f99592022-12-14 10:56:54 +0100744#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100746 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 }
Valerio Settia3f99592022-12-14 10:56:54 +0100748#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100750 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200752#endif
753
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100755
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100757 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100761 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100763
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100765 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100767
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100768exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100770
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000772}
773
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000775/*
776 * FIPS-180-2 test vectors
777 */
Valerio Settia3f99592022-12-14 10:56:54 +0100778static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000779{
780 { "abc" },
781 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
782 { "" }
783};
784
Valerio Settia3f99592022-12-14 10:56:54 +0100785static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000786{
787 3, 56, 1000
788};
789
Valerio Settia3f99592022-12-14 10:56:54 +0100790typedef const unsigned char (sha_test_sum_t)[32];
791
792/*
793 * SHA-224 test vectors
794 */
795#if defined(MBEDTLS_SHA224_C)
796static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000797{
Paul Bakker5121ce52009-01-03 21:22:43 +0000798 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
799 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
800 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
801 0xE3, 0x6C, 0x9D, 0xA7 },
802 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
803 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
804 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
805 0x52, 0x52, 0x25, 0x25 },
806 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
807 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
808 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100809 0x4E, 0xE7, 0xAD, 0x67 }
810};
811#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000812
Valerio Settia3f99592022-12-14 10:56:54 +0100813/*
814 * SHA-256 test vectors
815 */
816#if defined(MBEDTLS_SHA256_C)
817static sha_test_sum_t sha256_test_sum[] =
818{
Paul Bakker5121ce52009-01-03 21:22:43 +0000819 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
820 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
821 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
822 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
823 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
824 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
825 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
826 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
827 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
828 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
829 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
830 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
831};
Valerio Settia3f99592022-12-14 10:56:54 +0100832#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000833
834/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000835 * Checkup routine
836 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100837static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000838{
Valerio Settia3f99592022-12-14 10:56:54 +0100839 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500840 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200841 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000843
Valerio Settia3f99592022-12-14 10:56:54 +0100844#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100846#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100848#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100850#endif
851
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 buf = mbedtls_calloc(1024, sizeof(unsigned char));
853 if (NULL == buf) {
854 if (verbose != 0) {
855 mbedtls_printf("Buffer allocation failed\n");
856 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500857
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500859 }
860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 for (i = 0; i < 3; i++) {
864 if (verbose != 0) {
865 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
866 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100869 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 if (i == 2) {
873 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 for (int j = 0; j < 1000; j++) {
876 ret = mbedtls_sha256_update(&ctx, buf, buflen);
877 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100878 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100880 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 } else {
883 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
884 sha_test_buflen[i]);
885 if (ret != 0) {
886 goto fail;
887 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100888 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100891 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100893
Paul Bakker5121ce52009-01-03 21:22:43 +0000894
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100896 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100897 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100898 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000899
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 if (verbose != 0) {
901 mbedtls_printf("passed\n");
902 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000903 }
904
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 if (verbose != 0) {
906 mbedtls_printf("\n");
907 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100909 goto exit;
910
911fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 if (verbose != 0) {
913 mbedtls_printf("failed\n");
914 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100915
Paul Bakker5b4af392014-06-26 12:09:34 +0200916exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 mbedtls_sha256_free(&ctx);
918 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200919
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000921}
922
Valerio Settia3f99592022-12-14 10:56:54 +0100923#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100924int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100925{
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100927}
928#endif /* MBEDTLS_SHA256_C */
929
930#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100931int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100932{
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100934}
935#endif /* MBEDTLS_SHA224_C */
936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
Valerio Settia3f99592022-12-14 10:56:54 +0100939#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */