blob: 596b2c533f43499f760d50ab33f983d03c1b284d [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
Dave Rodgman8ba9f422023-10-08 10:46:25 +010025#if defined(__clang__) && (__clang_major__ >= 4)
26
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010027/* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if,
Dave Rodgman8ba9f422023-10-08 10:46:25 +010028 * but that is defined by build_info.h, and we need this block to happen first. */
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010029#if defined(__ARM_ARCH) && (__ARM_ARCH_PROFILE == 'A')
Dave Rodgman8ba9f422023-10-08 10:46:25 +010030#if __ARM_ARCH >= 8
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010031#define MBEDTLS_SHA256_ARCH_IS_ARMV8_A
Dave Rodgman8ba9f422023-10-08 10:46:25 +010032#endif
33#endif
34
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010035#if defined(MBEDTLS_SHA256_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO)
Jerry Yua135dee2023-02-16 16:56:22 +080036/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
37 *
Jerry Yufc2e1282023-02-27 11:16:56 +080038 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
39 * these are normally only enabled by the -march option on the command line.
40 * By defining the macros ourselves we gain access to those declarations without
41 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080042 *
Jerry Yufc2e1282023-02-27 11:16:56 +080043 * `arm_neon.h` could be included by any header file, so we put these defines
44 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080045 */
46#define __ARM_FEATURE_CRYPTO 1
Jerry Yuae129c32023-03-03 15:55:56 +080047/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
48 *
Jerry Yu490bf082023-03-06 15:21:44 +080049 * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
50 * for older compilers.
Jerry Yuae129c32023-03-03 15:55:56 +080051 */
52#define __ARM_FEATURE_SHA2 1
Dave Rodgmandb6ab242023-03-14 16:03:57 +000053#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
Jerry Yu490bf082023-03-06 15:21:44 +080054#endif
Jerry Yua135dee2023-02-16 16:56:22 +080055
Dave Rodgman8ba9f422023-10-08 10:46:25 +010056#endif /* defined(__clang__) && (__clang_major__ >= 4) */
57
Dave Rodgman7ed619d2023-10-05 09:39:56 +010058/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
59#define _GNU_SOURCE
60
Gilles Peskinedb09ef62020-06-03 01:43:33 +020061#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000062
Valerio Settia3f99592022-12-14 10:56:54 +010063#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000064
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000065#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050066#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000067#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000068
Rich Evans00ab4702015-02-06 13:43:58 +000069#include <string.h>
70
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000071#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010072
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010073#if defined(MBEDTLS_ARCH_IS_ARMV8_A)
Jerry Yu08933d32023-04-27 18:28:00 +080074
Dave Rodgman5b89c552023-10-10 14:59:02 +010075# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
76 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Dave Rodgman3ba9ce32023-10-05 09:58:33 +010077# ifdef __ARM_NEON
78# include <arm_neon.h>
79# else
Dave Rodgman5b89c552023-10-10 14:59:02 +010080# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Dave Rodgman3ba9ce32023-10-05 09:58:33 +010081# warning "Target does not support NEON instructions"
Dave Rodgman5b89c552023-10-10 14:59:02 +010082# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Dave Rodgman3ba9ce32023-10-05 09:58:33 +010083# else
84# error "Target does not support NEON instructions"
85# endif
86# endif
Jerry Yu6b00f5a2023-05-04 16:30:21 +080087# endif
88
Dave Rodgman5b89c552023-10-10 14:59:02 +010089# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
90 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Dave Rodgman790370b2023-10-05 11:01:31 +010091/* *INDENT-OFF* */
92
Dave Rodgman793e2642023-10-04 17:36:20 +010093# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
Jerry Yub1d06bb2023-05-05 14:05:07 +080094# if defined(__ARMCOMPILER_VERSION)
95# if __ARMCOMPILER_VERSION <= 6090000
Dave Rodgman5b89c552023-10-10 14:59:02 +010096# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yub1d06bb2023-05-05 14:05:07 +080097# endif
98# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
99# define MBEDTLS_POP_TARGET_PRAGMA
100# elif defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +0800101# if __clang_major__ < 4
Dave Rodgman5b89c552023-10-10 14:59:02 +0100102# error "A more recent Clang is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800103# endif
Jerry Yub1d06bb2023-05-05 14:05:07 +0800104# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800105# define MBEDTLS_POP_TARGET_PRAGMA
106# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +0000107 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
108 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +0800109 */
110# if __GNUC__ < 6
Dave Rodgman5b89c552023-10-10 14:59:02 +0100111# error "A more recent GCC is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800112# else
Jerry Yu2f2c0492023-02-16 14:24:46 +0800113# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800114# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +0800115# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800116# endif
117# else
Dave Rodgman5b89c552023-10-10 14:59:02 +0100118# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800119# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800120# endif
121/* *INDENT-ON* */
Jerry Yu08933d32023-04-27 18:28:00 +0800122
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000123# endif
Dave Rodgman5b89c552023-10-10 14:59:02 +0100124# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000125# if defined(__unix__)
126# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100127/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000128# include <sys/auxv.h>
Dave Rodgman66d55122023-10-23 15:12:32 +0100129/* These are not always defined via sys/auxv.h */
130# if !defined(HWCAP_SHA2)
131# define HWCAP_SHA2 (1 << 6)
132# endif
133# if !defined(HWCAP2_SHA2)
134# define HWCAP2_SHA2 (1 << 3)
135# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000136# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100137/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000138# include <signal.h>
139# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000140# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000141#elif defined(_M_ARM64)
Dave Rodgman5b89c552023-10-10 14:59:02 +0100142# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
143 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000144# include <arm64_neon.h>
145# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000146#else
Dave Rodgman5b89c552023-10-10 14:59:02 +0100147# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
148# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000149#endif
150
Dave Rodgman5b89c552023-10-10 14:59:02 +0100151#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000152/*
153 * Capability detection code comes early, so we can disable
Dave Rodgman5b89c552023-10-10 14:59:02 +0100154 * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000155 */
Dave Rodgman5d4ef832023-10-10 13:04:07 +0100156#if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100157static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000158{
Gilles Peskine449bd832023-01-11 14:50:10 +0100159 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000160}
Dave Rodgman5d4ef832023-10-10 13:04:07 +0100161#elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2)
162static int mbedtls_a64_crypto_sha256_determine_support(void)
163{
164 return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0;
165}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000166#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100167static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000168{
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000170}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000171#elif defined(_M_ARM64)
172#define WIN32_LEAN_AND_MEAN
173#include <Windows.h>
174#include <processthreadsapi.h>
175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000177{
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
179 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000180}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000181#elif defined(__unix__) && defined(SIG_SETMASK)
182/* Detection with SIGILL, setjmp() and longjmp() */
183#include <signal.h>
184#include <setjmp.h>
185
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000186static jmp_buf return_from_sigill;
187
188/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100189 * Armv8-A SHA256 support detection via SIGILL
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000190 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100191static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000192{
193 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000195}
196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000198{
199 struct sigaction old_action, new_action;
200
201 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 if (sigprocmask(0, NULL, &old_mask)) {
203 return 0;
204 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000207 new_action.sa_flags = 0;
208 new_action.sa_handler = sigill_handler;
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000211
212 static int ret = 0;
213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000215 /* If this traps, we will return a second time from setjmp() with 1 */
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100216#if defined(MBEDTLS_ARCH_IS_ARM64)
Dave Rodgman78d78462023-10-10 09:53:44 +0100217 asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100218#else
Dave Rodgman78d78462023-10-10 09:53:44 +0100219 asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100220#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000221 ret = 1;
222 }
223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 sigaction(SIGILL, &old_action, NULL);
225 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000226
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000228}
229#else
Dave Rodgman94a634d2023-10-10 12:59:29 +0100230#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
Dave Rodgman5b89c552023-10-10 14:59:02 +0100231#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000232#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
233
Dave Rodgman5b89c552023-10-10 14:59:02 +0100234#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000235
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200236#if !defined(MBEDTLS_SHA256_ALT)
237
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000238#define SHA256_BLOCK_SIZE 64
239
Gilles Peskine449bd832023-01-11 14:50:10 +0100240void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200241{
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200243}
244
Gilles Peskine449bd832023-01-11 14:50:10 +0100245void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200246{
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200248 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200252}
253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
255 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200256{
257 *dst = *src;
258}
259
Paul Bakker5121ce52009-01-03 21:22:43 +0000260/*
261 * SHA-256 context setup
262 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100263int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000264{
Valerio Settia3f99592022-12-14 10:56:54 +0100265#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100267 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 }
Valerio Settia3f99592022-12-14 10:56:54 +0100269#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100271 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 }
Valerio Settia3f99592022-12-14 10:56:54 +0100273#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100275 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200277#endif
278
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 ctx->total[0] = 0;
280 ctx->total[1] = 0;
281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100283#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 ctx->state[0] = 0x6A09E667;
285 ctx->state[1] = 0xBB67AE85;
286 ctx->state[2] = 0x3C6EF372;
287 ctx->state[3] = 0xA54FF53A;
288 ctx->state[4] = 0x510E527F;
289 ctx->state[5] = 0x9B05688C;
290 ctx->state[6] = 0x1F83D9AB;
291 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100292#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200294#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 ctx->state[0] = 0xC1059ED8;
296 ctx->state[1] = 0x367CD507;
297 ctx->state[2] = 0x3070DD17;
298 ctx->state[3] = 0xF70E5939;
299 ctx->state[4] = 0xFFC00B31;
300 ctx->state[5] = 0x68581511;
301 ctx->state[6] = 0x64F98FA7;
302 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200303#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000304 }
305
Valerio Settia3f99592022-12-14 10:56:54 +0100306#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000307 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100308#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000311}
312
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200314static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000315{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200316 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
317 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
318 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
319 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
320 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
321 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
322 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
323 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
324 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
325 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
326 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
327 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
328 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
329 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
330 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
331 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
332};
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334#endif
335
Dave Rodgman5b89c552023-10-10 14:59:02 +0100336#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
337 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000338
Dave Rodgman5b89c552023-10-10 14:59:02 +0100339#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000340# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
341# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
342#endif
343
344static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000346{
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
348 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000349
350 size_t processed = 0;
351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000353 len >= SHA256_BLOCK_SIZE;
354 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 msg += SHA256_BLOCK_SIZE,
356 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000357 uint32x4_t tmp, abcd_prev;
358
359 uint32x4_t abcd_orig = abcd;
360 uint32x4_t efgh_orig = efgh;
361
Dave Rodgman9a36f4c2023-10-05 11:25:52 +0100362 uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
363 uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
364 uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
365 uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000366
367#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
368 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
370 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
371 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
372 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000373#endif
374
375 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000377 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
379 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000380
381 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000383 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
385 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000386
387 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000389 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
391 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000392
393 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000395 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
397 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000400 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
402 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000403 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
405 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000406
407 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
409 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000410 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
412 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000413
414 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
416 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000417 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
419 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000420
421 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
423 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000424 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
426 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000427 }
428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 abcd = vaddq_u32(abcd, abcd_orig);
430 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000431 }
432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 vst1q_u32(&ctx->state[0], abcd);
434 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000437}
438
Dave Rodgman5b89c552023-10-10 14:59:02 +0100439#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100440/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100441 * This function is for internal use only if we are building both C and Armv8-A
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100442 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
443 */
444static
445#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100446int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
447 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000448{
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
450 SHA256_BLOCK_SIZE) ==
451 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000452}
453
Dave Rodgman5b89c552023-10-10 14:59:02 +0100454#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100455
Jerry Yu92fc5382023-02-16 11:17:11 +0800456#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800457#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800458#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800459#elif defined(__GNUC__)
460#pragma GCC pop_options
461#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800462#undef MBEDTLS_POP_TARGET_PRAGMA
463#endif
464
Dave Rodgman5b89c552023-10-10 14:59:02 +0100465#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000466#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
467#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
468#endif
469
470
471#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
Dave Rodgman5b89c552023-10-10 14:59:02 +0100472 !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
475#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
478#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
481#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
484#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200486#define R(t) \
487 ( \
488 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
489 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100490 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200493 do \
494 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
496 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200497 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
Dave Rodgman5b89c552023-10-10 14:59:02 +0100500#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100501/*
Dave Rodgman94a634d2023-10-10 12:59:29 +0100502 * This function is for internal use only if we are building both C and Armv8
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100503 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
504 */
505static
506#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100507int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
508 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200509{
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200511 uint32_t temp1, temp2, W[64];
512 uint32_t A[8];
513 } local;
514
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200515 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000516
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200518 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200520
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200521#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 for (i = 0; i < 64; i++) {
523 if (i < 16) {
524 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
525 } else {
526 R(i);
527 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
530 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200531
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200532 local.temp1 = local.A[7]; local.A[7] = local.A[6];
533 local.A[6] = local.A[5]; local.A[5] = local.A[4];
534 local.A[4] = local.A[3]; local.A[3] = local.A[2];
535 local.A[2] = local.A[1]; local.A[1] = local.A[0];
536 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200537 }
538#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 for (i = 0; i < 16; i++) {
540 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200541 }
542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 for (i = 0; i < 16; i += 8) {
544 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
545 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
546 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
547 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
548 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
549 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
550 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
551 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
552 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
553 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
554 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
555 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
556 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
557 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
558 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
559 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
560 }
561
562 for (i = 16; i < 64; i += 8) {
563 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
564 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
565 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
566 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
567 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
568 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
569 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
570 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
571 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
572 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
573 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
574 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
575 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
576 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
577 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
578 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200579 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200580#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200583 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100585
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200586 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100588
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000590}
Jaeden Amero041039f2018-02-19 15:28:08 +0000591
Dave Rodgman5b89c552023-10-10 14:59:02 +0100592#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000593
594
Dave Rodgman5b89c552023-10-10 14:59:02 +0100595#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000596
597static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000599{
600 size_t processed = 0;
601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 while (len >= SHA256_BLOCK_SIZE) {
603 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
604 return 0;
605 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000606
607 data += SHA256_BLOCK_SIZE;
608 len -= SHA256_BLOCK_SIZE;
609
610 processed += SHA256_BLOCK_SIZE;
611 }
612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000614}
615
Dave Rodgman5b89c552023-10-10 14:59:02 +0100616#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000617
618
Dave Rodgman5b89c552023-10-10 14:59:02 +0100619#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000622{
623 static int done = 0;
624 static int supported = 0;
625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000627 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000628 done = 1;
629 }
630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000632}
633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
635 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000636{
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 if (mbedtls_a64_crypto_sha256_has_support()) {
638 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
639 } else {
640 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
641 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000642}
643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
645 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000646{
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if (mbedtls_a64_crypto_sha256_has_support()) {
648 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
649 } else {
650 return mbedtls_internal_sha256_process_c(ctx, data);
651 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000652}
653
Dave Rodgman5b89c552023-10-10 14:59:02 +0100654#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000655
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
657/*
658 * SHA-256 process buffer
659 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100660int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
661 const unsigned char *input,
662 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000663{
Janos Follath24eed8d2019-11-22 13:21:35 +0000664 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000665 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000666 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 if (ilen == 0) {
669 return 0;
670 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000673 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
Paul Bakker5c2364c2012-10-01 14:41:15 +0000675 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000676 ctx->total[0] &= 0xFFFFFFFF;
677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000679 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 if (left && ilen >= fill) {
683 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
686 return ret;
687 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100688
Paul Bakker5121ce52009-01-03 21:22:43 +0000689 input += fill;
690 ilen -= fill;
691 left = 0;
692 }
693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000695 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 mbedtls_internal_sha256_process_many(ctx, input, ilen);
697 if (processed < SHA256_BLOCK_SIZE) {
698 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
699 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100700
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000701 input += processed;
702 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 }
704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 if (ilen > 0) {
706 memcpy((void *) (ctx->buffer + left), input, ilen);
707 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000710}
711
Paul Bakker5121ce52009-01-03 21:22:43 +0000712/*
713 * SHA-256 final digest
714 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100715int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
716 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000717{
Janos Follath24eed8d2019-11-22 13:21:35 +0000718 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200719 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000720 uint32_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100721 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200723 /*
724 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
725 */
726 used = ctx->total[0] & 0x3F;
727
728 ctx->buffer[used++] = 0x80;
729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200731 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 memset(ctx->buffer + used, 0, 56 - used);
733 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200734 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200736
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100738 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200742 }
743
744 /*
745 * Add message length
746 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 high = (ctx->total[0] >> 29)
748 | (ctx->total[1] << 3);
749 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
752 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100755 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100757
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200758 /*
759 * Output final state
760 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
762 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
763 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
764 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
765 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
766 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
767 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200769#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100770 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200771#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if (!truncated) {
773 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
774 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100775
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100776 ret = 0;
777
778exit:
779 mbedtls_sha256_free(ctx);
780 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000781}
782
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200784
Paul Bakker5121ce52009-01-03 21:22:43 +0000785/*
786 * output = SHA-256( input buffer )
787 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788int mbedtls_sha256(const unsigned char *input,
789 size_t ilen,
790 unsigned char *output,
791 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000792{
Janos Follath24eed8d2019-11-22 13:21:35 +0000793 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000795
Valerio Settia3f99592022-12-14 10:56:54 +0100796#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100798 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 }
Valerio Settia3f99592022-12-14 10:56:54 +0100800#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100802 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 }
Valerio Settia3f99592022-12-14 10:56:54 +0100804#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100806 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200808#endif
809
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100811
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100813 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100815
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100817 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100821 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100823
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100824exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100826
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000828}
829
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000831/*
832 * FIPS-180-2 test vectors
833 */
Valerio Settia3f99592022-12-14 10:56:54 +0100834static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000835{
836 { "abc" },
837 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
838 { "" }
839};
840
Valerio Settia3f99592022-12-14 10:56:54 +0100841static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000842{
843 3, 56, 1000
844};
845
Valerio Settia3f99592022-12-14 10:56:54 +0100846typedef const unsigned char (sha_test_sum_t)[32];
847
848/*
849 * SHA-224 test vectors
850 */
851#if defined(MBEDTLS_SHA224_C)
852static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000853{
Paul Bakker5121ce52009-01-03 21:22:43 +0000854 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
855 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
856 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
857 0xE3, 0x6C, 0x9D, 0xA7 },
858 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
859 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
860 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
861 0x52, 0x52, 0x25, 0x25 },
862 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
863 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
864 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100865 0x4E, 0xE7, 0xAD, 0x67 }
866};
867#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000868
Valerio Settia3f99592022-12-14 10:56:54 +0100869/*
870 * SHA-256 test vectors
871 */
872#if defined(MBEDTLS_SHA256_C)
873static sha_test_sum_t sha256_test_sum[] =
874{
Paul Bakker5121ce52009-01-03 21:22:43 +0000875 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
876 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
877 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
878 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
879 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
880 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
881 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
882 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
883 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
884 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
885 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
886 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
887};
Valerio Settia3f99592022-12-14 10:56:54 +0100888#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000889
890/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000891 * Checkup routine
892 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100893static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000894{
Valerio Settia3f99592022-12-14 10:56:54 +0100895 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500896 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200897 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200898 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000899
Valerio Settia3f99592022-12-14 10:56:54 +0100900#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100902#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100904#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100906#endif
907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 buf = mbedtls_calloc(1024, sizeof(unsigned char));
909 if (NULL == buf) {
910 if (verbose != 0) {
911 mbedtls_printf("Buffer allocation failed\n");
912 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500915 }
916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 for (i = 0; i < 3; i++) {
920 if (verbose != 0) {
921 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
922 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100925 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000927
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 if (i == 2) {
929 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 for (int j = 0; j < 1000; j++) {
932 ret = mbedtls_sha256_update(&ctx, buf, buflen);
933 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100934 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100936 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100937
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 } else {
939 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
940 sha_test_buflen[i]);
941 if (ret != 0) {
942 goto fail;
943 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100944 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100947 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100949
Paul Bakker5121ce52009-01-03 21:22:43 +0000950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100952 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100953 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100954 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 if (verbose != 0) {
957 mbedtls_printf("passed\n");
958 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 }
960
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 if (verbose != 0) {
962 mbedtls_printf("\n");
963 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000964
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100965 goto exit;
966
967fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 if (verbose != 0) {
969 mbedtls_printf("failed\n");
970 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100971
Paul Bakker5b4af392014-06-26 12:09:34 +0200972exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 mbedtls_sha256_free(&ctx);
974 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000977}
978
Valerio Settia3f99592022-12-14 10:56:54 +0100979#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100980int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100981{
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100983}
984#endif /* MBEDTLS_SHA256_C */
985
986#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100987int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100988{
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100990}
991#endif /* MBEDTLS_SHA224_C */
992
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000994
Valerio Settia3f99592022-12-14 10:56:54 +0100995#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */