blob: c9be73419729398b64fe670550254046a01034e9 [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 *
Dave Rodgmana0f10da2023-09-05 11:43:17 +010043 * `arm_neon.h` is included by common.h, so we put these defines
Jerry Yufc2e1282023-02-27 11:16:56 +080044 * 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 Rodgman6e51abf2023-10-25 15:17:11 +010077# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
Dave Rodgman5b89c552023-10-10 14:59:02 +010078# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Dave Rodgman3ba9ce32023-10-05 09:58:33 +010079# warning "Target does not support NEON instructions"
Dave Rodgman5b89c552023-10-10 14:59:02 +010080# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Dave Rodgman3ba9ce32023-10-05 09:58:33 +010081# else
82# error "Target does not support NEON instructions"
83# endif
84# endif
Jerry Yu6b00f5a2023-05-04 16:30:21 +080085# endif
86
Dave Rodgman5b89c552023-10-10 14:59:02 +010087# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
88 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Dave Rodgman790370b2023-10-05 11:01:31 +010089/* *INDENT-OFF* */
90
Dave Rodgman793e2642023-10-04 17:36:20 +010091# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
Jerry Yub1d06bb2023-05-05 14:05:07 +080092# if defined(__ARMCOMPILER_VERSION)
93# if __ARMCOMPILER_VERSION <= 6090000
Dave Rodgman5b89c552023-10-10 14:59:02 +010094# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yub1d06bb2023-05-05 14:05:07 +080095# endif
96# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
97# define MBEDTLS_POP_TARGET_PRAGMA
98# elif defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080099# if __clang_major__ < 4
Dave Rodgman5b89c552023-10-10 14:59:02 +0100100# error "A more recent Clang is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800101# endif
Jerry Yub1d06bb2023-05-05 14:05:07 +0800102# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800103# define MBEDTLS_POP_TARGET_PRAGMA
104# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +0000105 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
106 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +0800107 */
108# if __GNUC__ < 6
Dave Rodgman5b89c552023-10-10 14:59:02 +0100109# error "A more recent GCC is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800110# else
Jerry Yu2f2c0492023-02-16 14:24:46 +0800111# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800112# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +0800113# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800114# endif
115# else
Dave Rodgman5b89c552023-10-10 14:59:02 +0100116# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800117# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800118# endif
119/* *INDENT-ON* */
Jerry Yu08933d32023-04-27 18:28:00 +0800120
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000121# endif
Dave Rodgman5b89c552023-10-10 14:59:02 +0100122# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000123# if defined(__unix__)
124# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100125/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000126# include <sys/auxv.h>
Dave Rodgman66d55122023-10-23 15:12:32 +0100127/* These are not always defined via sys/auxv.h */
128# if !defined(HWCAP_SHA2)
129# define HWCAP_SHA2 (1 << 6)
130# endif
131# if !defined(HWCAP2_SHA2)
132# define HWCAP2_SHA2 (1 << 3)
133# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000134# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100135/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000136# include <signal.h>
137# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000138# endif
Dave Rodgman0a487172023-09-15 11:52:06 +0100139#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Dave Rodgman5b89c552023-10-10 14:59:02 +0100140# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
141# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000142#endif
143
Dave Rodgman5b89c552023-10-10 14:59:02 +0100144#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000145/*
146 * Capability detection code comes early, so we can disable
Dave Rodgman5b89c552023-10-10 14:59:02 +0100147 * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000148 */
Dave Rodgman5d4ef832023-10-10 13:04:07 +0100149#if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100150static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000151{
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000153}
Dave Rodgman5d4ef832023-10-10 13:04:07 +0100154#elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2)
155static int mbedtls_a64_crypto_sha256_determine_support(void)
156{
157 return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0;
158}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000159#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100160static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000161{
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000163}
Dave Rodgman0a487172023-09-15 11:52:06 +0100164#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000165#define WIN32_LEAN_AND_MEAN
166#include <Windows.h>
167#include <processthreadsapi.h>
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000170{
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
172 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000173}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000174#elif defined(__unix__) && defined(SIG_SETMASK)
175/* Detection with SIGILL, setjmp() and longjmp() */
176#include <signal.h>
177#include <setjmp.h>
178
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000179static jmp_buf return_from_sigill;
180
181/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100182 * Armv8-A SHA256 support detection via SIGILL
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000183 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100184static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000185{
186 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000188}
189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000191{
192 struct sigaction old_action, new_action;
193
194 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 if (sigprocmask(0, NULL, &old_mask)) {
196 return 0;
197 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000200 new_action.sa_flags = 0;
201 new_action.sa_handler = sigill_handler;
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000204
205 static int ret = 0;
206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000208 /* If this traps, we will return a second time from setjmp() with 1 */
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100209#if defined(MBEDTLS_ARCH_IS_ARM64)
Dave Rodgman78d78462023-10-10 09:53:44 +0100210 asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100211#else
Dave Rodgman78d78462023-10-10 09:53:44 +0100212 asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100213#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000214 ret = 1;
215 }
216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 sigaction(SIGILL, &old_action, NULL);
218 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000221}
222#else
Dave Rodgman94a634d2023-10-10 12:59:29 +0100223#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
Dave Rodgman5b89c552023-10-10 14:59:02 +0100224#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000225#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
226
Dave Rodgman5b89c552023-10-10 14:59:02 +0100227#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000228
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200229#if !defined(MBEDTLS_SHA256_ALT)
230
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000231#define SHA256_BLOCK_SIZE 64
232
Gilles Peskine449bd832023-01-11 14:50:10 +0100233void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200234{
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200236}
237
Gilles Peskine449bd832023-01-11 14:50:10 +0100238void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200239{
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200241 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200245}
246
Gilles Peskine449bd832023-01-11 14:50:10 +0100247void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
248 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200249{
250 *dst = *src;
251}
252
Paul Bakker5121ce52009-01-03 21:22:43 +0000253/*
254 * SHA-256 context setup
255 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100256int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000257{
Valerio Settia3f99592022-12-14 10:56:54 +0100258#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100260 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 }
Valerio Settia3f99592022-12-14 10:56:54 +0100262#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100264 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 }
Valerio Settia3f99592022-12-14 10:56:54 +0100266#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100268 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200270#endif
271
Paul Bakker5121ce52009-01-03 21:22:43 +0000272 ctx->total[0] = 0;
273 ctx->total[1] = 0;
274
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100276#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 ctx->state[0] = 0x6A09E667;
278 ctx->state[1] = 0xBB67AE85;
279 ctx->state[2] = 0x3C6EF372;
280 ctx->state[3] = 0xA54FF53A;
281 ctx->state[4] = 0x510E527F;
282 ctx->state[5] = 0x9B05688C;
283 ctx->state[6] = 0x1F83D9AB;
284 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100285#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200287#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 ctx->state[0] = 0xC1059ED8;
289 ctx->state[1] = 0x367CD507;
290 ctx->state[2] = 0x3070DD17;
291 ctx->state[3] = 0xF70E5939;
292 ctx->state[4] = 0xFFC00B31;
293 ctx->state[5] = 0x68581511;
294 ctx->state[6] = 0x64F98FA7;
295 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200296#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000297 }
298
Valerio Settia3f99592022-12-14 10:56:54 +0100299#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000300 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100301#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000304}
305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200307static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000308{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200309 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
310 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
311 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
312 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
313 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
314 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
315 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
316 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
317 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
318 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
319 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
320 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
321 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
322 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
323 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
324 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
325};
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000327#endif
328
Dave Rodgman5b89c552023-10-10 14:59:02 +0100329#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
330 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000331
Dave Rodgman5b89c552023-10-10 14:59:02 +0100332#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000333# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
334# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
335#endif
336
337static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000339{
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
341 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000342
343 size_t processed = 0;
344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000346 len >= SHA256_BLOCK_SIZE;
347 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 msg += SHA256_BLOCK_SIZE,
349 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000350 uint32x4_t tmp, abcd_prev;
351
352 uint32x4_t abcd_orig = abcd;
353 uint32x4_t efgh_orig = efgh;
354
Dave Rodgman9a36f4c2023-10-05 11:25:52 +0100355 uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
356 uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
357 uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
358 uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000359
360#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
361 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
363 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
364 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
365 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000366#endif
367
368 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000370 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
372 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000373
374 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000376 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
378 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000379
380 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000382 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
384 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000385
386 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000388 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
390 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000393 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
395 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000396 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
398 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000399
400 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
402 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
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 + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
409 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
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 + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
416 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
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
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 abcd = vaddq_u32(abcd, abcd_orig);
423 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000424 }
425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 vst1q_u32(&ctx->state[0], abcd);
427 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000430}
431
Dave Rodgman5b89c552023-10-10 14:59:02 +0100432#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100433/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100434 * This function is for internal use only if we are building both C and Armv8-A
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100435 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
436 */
437static
438#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100439int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
440 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000441{
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
443 SHA256_BLOCK_SIZE) ==
444 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000445}
446
Dave Rodgman5b89c552023-10-10 14:59:02 +0100447#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100448
Jerry Yu92fc5382023-02-16 11:17:11 +0800449#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800450#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800451#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800452#elif defined(__GNUC__)
453#pragma GCC pop_options
454#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800455#undef MBEDTLS_POP_TARGET_PRAGMA
456#endif
457
Dave Rodgman5b89c552023-10-10 14:59:02 +0100458#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000459#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
460#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
461#endif
462
463
464#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
Dave Rodgman5b89c552023-10-10 14:59:02 +0100465 !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
468#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
471#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
474#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
477#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200479#define R(t) \
480 ( \
481 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
482 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100483 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200486 do \
487 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
489 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200490 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
Dave Rodgman5b89c552023-10-10 14:59:02 +0100493#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100494/*
Dave Rodgman94a634d2023-10-10 12:59:29 +0100495 * This function is for internal use only if we are building both C and Armv8
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100496 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
497 */
498static
499#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100500int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
501 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200502{
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200504 uint32_t temp1, temp2, W[64];
505 uint32_t A[8];
506 } local;
507
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200508 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200511 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200513
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200514#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 for (i = 0; i < 64; i++) {
516 if (i < 16) {
517 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
518 } else {
519 R(i);
520 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
523 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200524
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200525 local.temp1 = local.A[7]; local.A[7] = local.A[6];
526 local.A[6] = local.A[5]; local.A[5] = local.A[4];
527 local.A[4] = local.A[3]; local.A[3] = local.A[2];
528 local.A[2] = local.A[1]; local.A[1] = local.A[0];
529 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200530 }
531#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 for (i = 0; i < 16; i++) {
533 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200534 }
535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 for (i = 0; i < 16; i += 8) {
537 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
538 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
539 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
540 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
541 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
542 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
543 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
544 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
545 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
546 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
547 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
548 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
549 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
550 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
551 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
552 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
553 }
554
555 for (i = 16; i < 64; i += 8) {
556 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
557 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
558 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
559 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
560 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
561 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
562 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
563 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
564 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
565 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
566 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
567 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
568 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
569 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
570 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
571 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200572 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200573#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200574
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200576 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100578
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200579 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000583}
Jaeden Amero041039f2018-02-19 15:28:08 +0000584
Dave Rodgman5b89c552023-10-10 14:59:02 +0100585#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000586
587
Dave Rodgman5b89c552023-10-10 14:59:02 +0100588#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000589
590static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000592{
593 size_t processed = 0;
594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 while (len >= SHA256_BLOCK_SIZE) {
596 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
597 return 0;
598 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000599
600 data += SHA256_BLOCK_SIZE;
601 len -= SHA256_BLOCK_SIZE;
602
603 processed += SHA256_BLOCK_SIZE;
604 }
605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000607}
608
Dave Rodgman5b89c552023-10-10 14:59:02 +0100609#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000610
611
Dave Rodgman5b89c552023-10-10 14:59:02 +0100612#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000615{
616 static int done = 0;
617 static int supported = 0;
618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000620 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000621 done = 1;
622 }
623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000625}
626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
628 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000629{
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if (mbedtls_a64_crypto_sha256_has_support()) {
631 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
632 } else {
633 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
634 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000635}
636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
638 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000639{
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (mbedtls_a64_crypto_sha256_has_support()) {
641 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
642 } else {
643 return mbedtls_internal_sha256_process_c(ctx, data);
644 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000645}
646
Dave Rodgman5b89c552023-10-10 14:59:02 +0100647#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000648
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650/*
651 * SHA-256 process buffer
652 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100653int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
654 const unsigned char *input,
655 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000656{
Janos Follath24eed8d2019-11-22 13:21:35 +0000657 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000658 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000659 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 if (ilen == 0) {
662 return 0;
663 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
665 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000666 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
Paul Bakker5c2364c2012-10-01 14:41:15 +0000668 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000669 ctx->total[0] &= 0xFFFFFFFF;
670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000672 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 if (left && ilen >= fill) {
676 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
679 return ret;
680 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100681
Paul Bakker5121ce52009-01-03 21:22:43 +0000682 input += fill;
683 ilen -= fill;
684 left = 0;
685 }
686
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000688 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 mbedtls_internal_sha256_process_many(ctx, input, ilen);
690 if (processed < SHA256_BLOCK_SIZE) {
691 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
692 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100693
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000694 input += processed;
695 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 }
697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 if (ilen > 0) {
699 memcpy((void *) (ctx->buffer + left), input, ilen);
700 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100701
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000703}
704
Paul Bakker5121ce52009-01-03 21:22:43 +0000705/*
706 * SHA-256 final digest
707 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100708int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
709 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000710{
Janos Follath24eed8d2019-11-22 13:21:35 +0000711 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200712 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000713 uint32_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100714 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200716 /*
717 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
718 */
719 used = ctx->total[0] & 0x3F;
720
721 ctx->buffer[used++] = 0x80;
722
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200724 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 memset(ctx->buffer + used, 0, 56 - used);
726 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200727 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100731 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200735 }
736
737 /*
738 * Add message length
739 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 high = (ctx->total[0] >> 29)
741 | (ctx->total[1] << 3);
742 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
745 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100748 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100750
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200751 /*
752 * Output final state
753 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
755 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
756 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
757 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
758 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
759 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
760 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000761
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200762#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100763 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200764#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if (!truncated) {
766 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
767 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100768
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100769 ret = 0;
770
771exit:
772 mbedtls_sha256_free(ctx);
773 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000774}
775
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200777
Paul Bakker5121ce52009-01-03 21:22:43 +0000778/*
779 * output = SHA-256( input buffer )
780 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100781int mbedtls_sha256(const unsigned char *input,
782 size_t ilen,
783 unsigned char *output,
784 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000785{
Janos Follath24eed8d2019-11-22 13:21:35 +0000786 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000788
Valerio Settia3f99592022-12-14 10:56:54 +0100789#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100791 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 }
Valerio Settia3f99592022-12-14 10:56:54 +0100793#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100795 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 }
Valerio Settia3f99592022-12-14 10:56:54 +0100797#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100799 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200801#endif
802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100806 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100810 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100812
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100814 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100816
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100817exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000821}
822
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000824/*
825 * FIPS-180-2 test vectors
826 */
Valerio Settia3f99592022-12-14 10:56:54 +0100827static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000828{
829 { "abc" },
830 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
831 { "" }
832};
833
Valerio Settia3f99592022-12-14 10:56:54 +0100834static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000835{
836 3, 56, 1000
837};
838
Valerio Settia3f99592022-12-14 10:56:54 +0100839typedef const unsigned char (sha_test_sum_t)[32];
840
841/*
842 * SHA-224 test vectors
843 */
844#if defined(MBEDTLS_SHA224_C)
845static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000846{
Paul Bakker5121ce52009-01-03 21:22:43 +0000847 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
848 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
849 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
850 0xE3, 0x6C, 0x9D, 0xA7 },
851 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
852 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
853 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
854 0x52, 0x52, 0x25, 0x25 },
855 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
856 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
857 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100858 0x4E, 0xE7, 0xAD, 0x67 }
859};
860#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Valerio Settia3f99592022-12-14 10:56:54 +0100862/*
863 * SHA-256 test vectors
864 */
865#if defined(MBEDTLS_SHA256_C)
866static sha_test_sum_t sha256_test_sum[] =
867{
Paul Bakker5121ce52009-01-03 21:22:43 +0000868 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
869 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
870 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
871 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
872 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
873 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
874 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
875 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
876 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
877 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
878 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
879 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
880};
Valerio Settia3f99592022-12-14 10:56:54 +0100881#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000882
883/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000884 * Checkup routine
885 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100886static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000887{
Valerio Settia3f99592022-12-14 10:56:54 +0100888 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500889 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200890 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
Valerio Settia3f99592022-12-14 10:56:54 +0100893#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100895#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100897#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100899#endif
900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 buf = mbedtls_calloc(1024, sizeof(unsigned char));
902 if (NULL == buf) {
903 if (verbose != 0) {
904 mbedtls_printf("Buffer allocation failed\n");
905 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500908 }
909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 for (i = 0; i < 3; i++) {
913 if (verbose != 0) {
914 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
915 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100918 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 if (i == 2) {
922 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 for (int j = 0; j < 1000; j++) {
925 ret = mbedtls_sha256_update(&ctx, buf, buflen);
926 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100927 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100929 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 } else {
932 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
933 sha_test_buflen[i]);
934 if (ret != 0) {
935 goto fail;
936 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100937 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100940 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100942
Paul Bakker5121ce52009-01-03 21:22:43 +0000943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100945 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100946 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100947 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 if (verbose != 0) {
950 mbedtls_printf("passed\n");
951 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000952 }
953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 if (verbose != 0) {
955 mbedtls_printf("\n");
956 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000957
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100958 goto exit;
959
960fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 if (verbose != 0) {
962 mbedtls_printf("failed\n");
963 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100964
Paul Bakker5b4af392014-06-26 12:09:34 +0200965exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 mbedtls_sha256_free(&ctx);
967 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000970}
971
Valerio Settia3f99592022-12-14 10:56:54 +0100972#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100973int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100974{
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100976}
977#endif /* MBEDTLS_SHA256_C */
978
979#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100980int mbedtls_sha224_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, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100983}
984#endif /* MBEDTLS_SHA224_C */
985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000987
Valerio Settia3f99592022-12-14 10:56:54 +0100988#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */