blob: a6d0a7a46d5616254b10ff6ffe1768b010df9a4d [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 Rodgman5d4ef832023-10-10 13:04:07 +0100129# include <asm/hwcap.h>
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000130# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100131/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000132# include <signal.h>
133# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000134# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000135#elif defined(_M_ARM64)
Dave Rodgman5b89c552023-10-10 14:59:02 +0100136# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
137 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000138# include <arm64_neon.h>
139# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000140#else
Dave Rodgman5b89c552023-10-10 14:59:02 +0100141# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
142# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000143#endif
144
Dave Rodgman5b89c552023-10-10 14:59:02 +0100145#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000146/*
147 * Capability detection code comes early, so we can disable
Dave Rodgman5b89c552023-10-10 14:59:02 +0100148 * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000149 */
Dave Rodgman5d4ef832023-10-10 13:04:07 +0100150#if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100151static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000152{
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000154}
Dave Rodgman5d4ef832023-10-10 13:04:07 +0100155#elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2)
156static int mbedtls_a64_crypto_sha256_determine_support(void)
157{
158 return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0;
159}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000160#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100161static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000162{
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000164}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000165#elif defined(_M_ARM64)
166#define WIN32_LEAN_AND_MEAN
167#include <Windows.h>
168#include <processthreadsapi.h>
169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000171{
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
173 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000174}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000175#elif defined(__unix__) && defined(SIG_SETMASK)
176/* Detection with SIGILL, setjmp() and longjmp() */
177#include <signal.h>
178#include <setjmp.h>
179
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000180static jmp_buf return_from_sigill;
181
182/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100183 * Armv8-A SHA256 support detection via SIGILL
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000184 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100185static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000186{
187 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000189}
190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000192{
193 struct sigaction old_action, new_action;
194
195 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 if (sigprocmask(0, NULL, &old_mask)) {
197 return 0;
198 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000201 new_action.sa_flags = 0;
202 new_action.sa_handler = sigill_handler;
203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000205
206 static int ret = 0;
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000209 /* If this traps, we will return a second time from setjmp() with 1 */
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100210#if defined(MBEDTLS_ARCH_IS_ARM64)
Dave Rodgman78d78462023-10-10 09:53:44 +0100211 asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100212#else
Dave Rodgman78d78462023-10-10 09:53:44 +0100213 asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100214#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000215 ret = 1;
216 }
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 sigaction(SIGILL, &old_action, NULL);
219 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000222}
223#else
Dave Rodgman94a634d2023-10-10 12:59:29 +0100224#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
Dave Rodgman5b89c552023-10-10 14:59:02 +0100225#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000226#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
227
Dave Rodgman5b89c552023-10-10 14:59:02 +0100228#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000229
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200230#if !defined(MBEDTLS_SHA256_ALT)
231
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000232#define SHA256_BLOCK_SIZE 64
233
Gilles Peskine449bd832023-01-11 14:50:10 +0100234void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200235{
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200237}
238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200240{
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200242 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200244
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200246}
247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
249 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200250{
251 *dst = *src;
252}
253
Paul Bakker5121ce52009-01-03 21:22:43 +0000254/*
255 * SHA-256 context setup
256 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100257int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000258{
Valerio Settia3f99592022-12-14 10:56:54 +0100259#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100261 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 }
Valerio Settia3f99592022-12-14 10:56:54 +0100263#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100265 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 }
Valerio Settia3f99592022-12-14 10:56:54 +0100267#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100269 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200271#endif
272
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 ctx->total[0] = 0;
274 ctx->total[1] = 0;
275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100277#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 ctx->state[0] = 0x6A09E667;
279 ctx->state[1] = 0xBB67AE85;
280 ctx->state[2] = 0x3C6EF372;
281 ctx->state[3] = 0xA54FF53A;
282 ctx->state[4] = 0x510E527F;
283 ctx->state[5] = 0x9B05688C;
284 ctx->state[6] = 0x1F83D9AB;
285 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100286#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200288#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 ctx->state[0] = 0xC1059ED8;
290 ctx->state[1] = 0x367CD507;
291 ctx->state[2] = 0x3070DD17;
292 ctx->state[3] = 0xF70E5939;
293 ctx->state[4] = 0xFFC00B31;
294 ctx->state[5] = 0x68581511;
295 ctx->state[6] = 0x64F98FA7;
296 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200297#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 }
299
Valerio Settia3f99592022-12-14 10:56:54 +0100300#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000301 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100302#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100303
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000305}
306
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200308static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000309{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200310 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
311 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
312 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
313 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
314 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
315 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
316 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
317 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
318 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
319 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
320 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
321 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
322 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
323 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
324 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
325 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
326};
Paul Bakker5121ce52009-01-03 21:22:43 +0000327
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000328#endif
329
Dave Rodgman5b89c552023-10-10 14:59:02 +0100330#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
331 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000332
Dave Rodgman5b89c552023-10-10 14:59:02 +0100333#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
335# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
336#endif
337
338static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000340{
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
342 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000343
344 size_t processed = 0;
345
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000347 len >= SHA256_BLOCK_SIZE;
348 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 msg += SHA256_BLOCK_SIZE,
350 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000351 uint32x4_t tmp, abcd_prev;
352
353 uint32x4_t abcd_orig = abcd;
354 uint32x4_t efgh_orig = efgh;
355
Dave Rodgman9a36f4c2023-10-05 11:25:52 +0100356 uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
357 uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
358 uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
359 uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000360
361#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
362 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
364 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
365 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
366 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000367#endif
368
369 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000371 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
373 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000374
375 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
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 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
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 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
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
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000394 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
396 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000397 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
399 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000400
401 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
403 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000404 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
406 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000407
408 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
410 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000411 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
413 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000414
415 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
417 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000418 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
420 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000421 }
422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 abcd = vaddq_u32(abcd, abcd_orig);
424 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000425 }
426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 vst1q_u32(&ctx->state[0], abcd);
428 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000429
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000431}
432
Dave Rodgman5b89c552023-10-10 14:59:02 +0100433#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100434/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100435 * This function is for internal use only if we are building both C and Armv8-A
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100436 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
437 */
438static
439#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100440int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
441 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000442{
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
444 SHA256_BLOCK_SIZE) ==
445 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000446}
447
Dave Rodgman5b89c552023-10-10 14:59:02 +0100448#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100449
Jerry Yu92fc5382023-02-16 11:17:11 +0800450#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800451#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800452#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800453#elif defined(__GNUC__)
454#pragma GCC pop_options
455#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800456#undef MBEDTLS_POP_TARGET_PRAGMA
457#endif
458
Dave Rodgman5b89c552023-10-10 14:59:02 +0100459#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000460#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
461#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
462#endif
463
464
465#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
Dave Rodgman5b89c552023-10-10 14:59:02 +0100466 !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
469#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
472#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
475#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
478#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200480#define R(t) \
481 ( \
482 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
483 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100484 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200487 do \
488 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
490 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200491 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000493
Dave Rodgman5b89c552023-10-10 14:59:02 +0100494#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100495/*
Dave Rodgman94a634d2023-10-10 12:59:29 +0100496 * This function is for internal use only if we are building both C and Armv8
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100497 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
498 */
499static
500#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100501int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
502 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200503{
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200505 uint32_t temp1, temp2, W[64];
506 uint32_t A[8];
507 } local;
508
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200509 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200512 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200514
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200515#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 for (i = 0; i < 64; i++) {
517 if (i < 16) {
518 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
519 } else {
520 R(i);
521 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200522
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
524 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200525
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200526 local.temp1 = local.A[7]; local.A[7] = local.A[6];
527 local.A[6] = local.A[5]; local.A[5] = local.A[4];
528 local.A[4] = local.A[3]; local.A[3] = local.A[2];
529 local.A[2] = local.A[1]; local.A[1] = local.A[0];
530 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200531 }
532#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 for (i = 0; i < 16; i++) {
534 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200535 }
536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 for (i = 0; i < 16; i += 8) {
538 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
539 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
540 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
541 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
542 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
543 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
544 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
545 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
546 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
547 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
548 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
549 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
550 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
551 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
552 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
553 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
554 }
555
556 for (i = 16; i < 64; i += 8) {
557 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
558 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
559 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
560 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
561 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
562 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
563 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
564 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
565 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
566 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
567 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
568 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
569 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
570 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
571 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
572 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200573 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200574#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200577 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100579
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200580 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000584}
Jaeden Amero041039f2018-02-19 15:28:08 +0000585
Dave Rodgman5b89c552023-10-10 14:59:02 +0100586#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000587
588
Dave Rodgman5b89c552023-10-10 14:59:02 +0100589#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000590
591static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000593{
594 size_t processed = 0;
595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 while (len >= SHA256_BLOCK_SIZE) {
597 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
598 return 0;
599 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000600
601 data += SHA256_BLOCK_SIZE;
602 len -= SHA256_BLOCK_SIZE;
603
604 processed += SHA256_BLOCK_SIZE;
605 }
606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000608}
609
Dave Rodgman5b89c552023-10-10 14:59:02 +0100610#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000611
612
Dave Rodgman5b89c552023-10-10 14:59:02 +0100613#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000616{
617 static int done = 0;
618 static int supported = 0;
619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000621 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000622 done = 1;
623 }
624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000626}
627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
629 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000630{
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 if (mbedtls_a64_crypto_sha256_has_support()) {
632 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
633 } else {
634 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
635 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000636}
637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
639 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000640{
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 if (mbedtls_a64_crypto_sha256_has_support()) {
642 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
643 } else {
644 return mbedtls_internal_sha256_process_c(ctx, data);
645 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000646}
647
Dave Rodgman5b89c552023-10-10 14:59:02 +0100648#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000649
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
651/*
652 * SHA-256 process buffer
653 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100654int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
655 const unsigned char *input,
656 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000657{
Janos Follath24eed8d2019-11-22 13:21:35 +0000658 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000659 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000660 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 if (ilen == 0) {
663 return 0;
664 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
666 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000667 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
Paul Bakker5c2364c2012-10-01 14:41:15 +0000669 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 ctx->total[0] &= 0xFFFFFFFF;
671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 if (left && ilen >= fill) {
677 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
680 return ret;
681 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100682
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 input += fill;
684 ilen -= fill;
685 left = 0;
686 }
687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000689 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 mbedtls_internal_sha256_process_many(ctx, input, ilen);
691 if (processed < SHA256_BLOCK_SIZE) {
692 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
693 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100694
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000695 input += processed;
696 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000697 }
698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 if (ilen > 0) {
700 memcpy((void *) (ctx->buffer + left), input, ilen);
701 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100702
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000704}
705
Paul Bakker5121ce52009-01-03 21:22:43 +0000706/*
707 * SHA-256 final digest
708 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100709int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
710 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000711{
Janos Follath24eed8d2019-11-22 13:21:35 +0000712 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200713 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000714 uint32_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100715 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000716
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200717 /*
718 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
719 */
720 used = ctx->total[0] & 0x3F;
721
722 ctx->buffer[used++] = 0x80;
723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200725 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 memset(ctx->buffer + used, 0, 56 - used);
727 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200728 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200730
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100732 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200736 }
737
738 /*
739 * Add message length
740 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 high = (ctx->total[0] >> 29)
742 | (ctx->total[1] << 3);
743 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000744
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
746 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000747
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100749 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100751
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200752 /*
753 * Output final state
754 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
756 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
757 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
758 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
759 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
760 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
761 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000762
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200763#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100764 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200765#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 if (!truncated) {
767 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
768 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100769
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100770 ret = 0;
771
772exit:
773 mbedtls_sha256_free(ctx);
774 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000775}
776
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200778
Paul Bakker5121ce52009-01-03 21:22:43 +0000779/*
780 * output = SHA-256( input buffer )
781 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100782int mbedtls_sha256(const unsigned char *input,
783 size_t ilen,
784 unsigned char *output,
785 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000786{
Janos Follath24eed8d2019-11-22 13:21:35 +0000787 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000789
Valerio Settia3f99592022-12-14 10:56:54 +0100790#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100792 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 }
Valerio Settia3f99592022-12-14 10:56:54 +0100794#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100796 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 }
Valerio Settia3f99592022-12-14 10:56:54 +0100798#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100800 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200802#endif
803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100805
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100807 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100809
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100811 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100815 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100817
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100818exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100820
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000822}
823
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000825/*
826 * FIPS-180-2 test vectors
827 */
Valerio Settia3f99592022-12-14 10:56:54 +0100828static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000829{
830 { "abc" },
831 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
832 { "" }
833};
834
Valerio Settia3f99592022-12-14 10:56:54 +0100835static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000836{
837 3, 56, 1000
838};
839
Valerio Settia3f99592022-12-14 10:56:54 +0100840typedef const unsigned char (sha_test_sum_t)[32];
841
842/*
843 * SHA-224 test vectors
844 */
845#if defined(MBEDTLS_SHA224_C)
846static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000847{
Paul Bakker5121ce52009-01-03 21:22:43 +0000848 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
849 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
850 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
851 0xE3, 0x6C, 0x9D, 0xA7 },
852 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
853 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
854 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
855 0x52, 0x52, 0x25, 0x25 },
856 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
857 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
858 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100859 0x4E, 0xE7, 0xAD, 0x67 }
860};
861#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
Valerio Settia3f99592022-12-14 10:56:54 +0100863/*
864 * SHA-256 test vectors
865 */
866#if defined(MBEDTLS_SHA256_C)
867static sha_test_sum_t sha256_test_sum[] =
868{
Paul Bakker5121ce52009-01-03 21:22:43 +0000869 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
870 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
871 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
872 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
873 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
874 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
875 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
876 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
877 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
878 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
879 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
880 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
881};
Valerio Settia3f99592022-12-14 10:56:54 +0100882#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
884/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000885 * Checkup routine
886 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100887static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000888{
Valerio Settia3f99592022-12-14 10:56:54 +0100889 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500890 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200891 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000893
Valerio Settia3f99592022-12-14 10:56:54 +0100894#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100896#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100898#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100900#endif
901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 buf = mbedtls_calloc(1024, sizeof(unsigned char));
903 if (NULL == buf) {
904 if (verbose != 0) {
905 mbedtls_printf("Buffer allocation failed\n");
906 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500909 }
910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 for (i = 0; i < 3; i++) {
914 if (verbose != 0) {
915 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
916 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100919 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 if (i == 2) {
923 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000924
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 for (int j = 0; j < 1000; j++) {
926 ret = mbedtls_sha256_update(&ctx, buf, buflen);
927 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100928 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100930 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 } else {
933 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
934 sha_test_buflen[i]);
935 if (ret != 0) {
936 goto fail;
937 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100938 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100941 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100943
Paul Bakker5121ce52009-01-03 21:22:43 +0000944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100946 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100947 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100948 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 if (verbose != 0) {
951 mbedtls_printf("passed\n");
952 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 }
954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 if (verbose != 0) {
956 mbedtls_printf("\n");
957 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100959 goto exit;
960
961fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 if (verbose != 0) {
963 mbedtls_printf("failed\n");
964 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100965
Paul Bakker5b4af392014-06-26 12:09:34 +0200966exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 mbedtls_sha256_free(&ctx);
968 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000971}
972
Valerio Settia3f99592022-12-14 10:56:54 +0100973#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100974int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100975{
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100977}
978#endif /* MBEDTLS_SHA256_C */
979
980#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100981int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100982{
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100984}
985#endif /* MBEDTLS_SHA224_C */
986
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000988
Valerio Settia3f99592022-12-14 10:56:54 +0100989#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */