blob: 339fa84422288f40e3ca7661b654c9267726ec71 [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
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
9 *
10 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
11 */
12
Dave Rodgman8ba9f422023-10-08 10:46:25 +010013#if defined(__clang__) && (__clang_major__ >= 4)
14
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010015/* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if,
Dave Rodgman8ba9f422023-10-08 10:46:25 +010016 * but that is defined by build_info.h, and we need this block to happen first. */
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010017#if defined(__ARM_ARCH) && (__ARM_ARCH_PROFILE == 'A')
Dave Rodgman8ba9f422023-10-08 10:46:25 +010018#if __ARM_ARCH >= 8
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010019#define MBEDTLS_SHA256_ARCH_IS_ARMV8_A
Dave Rodgman8ba9f422023-10-08 10:46:25 +010020#endif
21#endif
22
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010023#if defined(MBEDTLS_SHA256_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO)
Jerry Yua135dee2023-02-16 16:56:22 +080024/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
25 *
Jerry Yufc2e1282023-02-27 11:16:56 +080026 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
27 * these are normally only enabled by the -march option on the command line.
28 * By defining the macros ourselves we gain access to those declarations without
29 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080030 *
Dave Rodgmana0f10da2023-09-05 11:43:17 +010031 * `arm_neon.h` is included by common.h, so we put these defines
Jerry Yufc2e1282023-02-27 11:16:56 +080032 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080033 */
34#define __ARM_FEATURE_CRYPTO 1
Jerry Yuae129c32023-03-03 15:55:56 +080035/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
36 *
Jerry Yu490bf082023-03-06 15:21:44 +080037 * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
38 * for older compilers.
Jerry Yuae129c32023-03-03 15:55:56 +080039 */
40#define __ARM_FEATURE_SHA2 1
Dave Rodgmandb6ab242023-03-14 16:03:57 +000041#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
Jerry Yu490bf082023-03-06 15:21:44 +080042#endif
Jerry Yua135dee2023-02-16 16:56:22 +080043
Dave Rodgman8ba9f422023-10-08 10:46:25 +010044#endif /* defined(__clang__) && (__clang_major__ >= 4) */
45
Dave Rodgman7ed619d2023-10-05 09:39:56 +010046/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
nilesh.kaled338d012024-04-02 18:10:39 +053047#if !defined(_GNU_SOURCE)
Dave Rodgman7ed619d2023-10-05 09:39:56 +010048#define _GNU_SOURCE
nilesh.kaled338d012024-04-02 18:10:39 +053049#endif
Dave Rodgman7ed619d2023-10-05 09:39:56 +010050
Gilles Peskinedb09ef62020-06-03 01:43:33 +020051#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000052
Valerio Settia3f99592022-12-14 10:56:54 +010053#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000054
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050056#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000057#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000058
Rich Evans00ab4702015-02-06 13:43:58 +000059#include <string.h>
60
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010062
Dave Rodgmanfe9fda82023-10-10 14:51:06 +010063#if defined(MBEDTLS_ARCH_IS_ARMV8_A)
Jerry Yu08933d32023-04-27 18:28:00 +080064
Dave Rodgman5b89c552023-10-10 14:59:02 +010065# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
66 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Dave Rodgman6e51abf2023-10-25 15:17:11 +010067# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
Dave Rodgman5b89c552023-10-10 14:59:02 +010068# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Dave Rodgman3ba9ce32023-10-05 09:58:33 +010069# warning "Target does not support NEON instructions"
Dave Rodgman5b89c552023-10-10 14:59:02 +010070# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Dave Rodgman3ba9ce32023-10-05 09:58:33 +010071# else
72# error "Target does not support NEON instructions"
73# endif
74# endif
Jerry Yu6b00f5a2023-05-04 16:30:21 +080075# endif
76
Dave Rodgman5b89c552023-10-10 14:59:02 +010077# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
78 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Dave Rodgman790370b2023-10-05 11:01:31 +010079/* *INDENT-OFF* */
80
Dave Rodgman793e2642023-10-04 17:36:20 +010081# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
Jerry Yub1d06bb2023-05-05 14:05:07 +080082# if defined(__ARMCOMPILER_VERSION)
83# if __ARMCOMPILER_VERSION <= 6090000
Dave Rodgman5b89c552023-10-10 14:59:02 +010084# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yub1d06bb2023-05-05 14:05:07 +080085# endif
86# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
87# define MBEDTLS_POP_TARGET_PRAGMA
88# elif defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080089# if __clang_major__ < 4
Dave Rodgman5b89c552023-10-10 14:59:02 +010090# error "A more recent Clang is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080091# endif
Jerry Yub1d06bb2023-05-05 14:05:07 +080092# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080093# define MBEDTLS_POP_TARGET_PRAGMA
94# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +000095 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
96 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +080097 */
98# if __GNUC__ < 6
Dave Rodgman5b89c552023-10-10 14:59:02 +010099# error "A more recent GCC is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800100# else
Jerry Yu2f2c0492023-02-16 14:24:46 +0800101# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800102# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +0800103# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800104# endif
105# else
Dave Rodgman5b89c552023-10-10 14:59:02 +0100106# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +0800107# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800108# endif
109/* *INDENT-ON* */
Jerry Yu08933d32023-04-27 18:28:00 +0800110
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000111# endif
Dave Rodgman5b89c552023-10-10 14:59:02 +0100112# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000113# if defined(__unix__)
114# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100115/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000116# include <sys/auxv.h>
Dave Rodgman66d55122023-10-23 15:12:32 +0100117/* These are not always defined via sys/auxv.h */
118# if !defined(HWCAP_SHA2)
119# define HWCAP_SHA2 (1 << 6)
120# endif
121# if !defined(HWCAP2_SHA2)
122# define HWCAP2_SHA2 (1 << 3)
123# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000124# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100125/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000126# include <signal.h>
127# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000128# endif
Dave Rodgman0a487172023-09-15 11:52:06 +0100129#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Dave Rodgman5b89c552023-10-10 14:59:02 +0100130# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
131# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000132#endif
133
Dave Rodgman5b89c552023-10-10 14:59:02 +0100134#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000135/*
136 * Capability detection code comes early, so we can disable
Dave Rodgman5b89c552023-10-10 14:59:02 +0100137 * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000138 */
Dave Rodgman5d4ef832023-10-10 13:04:07 +0100139#if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100140static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000141{
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000143}
Dave Rodgman5d4ef832023-10-10 13:04:07 +0100144#elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2)
145static int mbedtls_a64_crypto_sha256_determine_support(void)
146{
147 return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0;
148}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000149#elif defined(__APPLE__)
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 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000153}
Dave Rodgman0a487172023-09-15 11:52:06 +0100154#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000155#define WIN32_LEAN_AND_MEAN
156#include <Windows.h>
157#include <processthreadsapi.h>
158
Gilles Peskine449bd832023-01-11 14:50:10 +0100159static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000160{
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
162 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000163}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000164#elif defined(__unix__) && defined(SIG_SETMASK)
165/* Detection with SIGILL, setjmp() and longjmp() */
166#include <signal.h>
167#include <setjmp.h>
168
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000169static jmp_buf return_from_sigill;
170
171/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100172 * Armv8-A SHA256 support detection via SIGILL
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000173 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100174static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000175{
176 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000178}
179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000181{
182 struct sigaction old_action, new_action;
183
184 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 if (sigprocmask(0, NULL, &old_mask)) {
186 return 0;
187 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000188
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000190 new_action.sa_flags = 0;
191 new_action.sa_handler = sigill_handler;
192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000194
195 static int ret = 0;
196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000198 /* If this traps, we will return a second time from setjmp() with 1 */
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100199#if defined(MBEDTLS_ARCH_IS_ARM64)
Dave Rodgman78d78462023-10-10 09:53:44 +0100200 asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100201#else
Dave Rodgman78d78462023-10-10 09:53:44 +0100202 asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100203#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000204 ret = 1;
205 }
206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 sigaction(SIGILL, &old_action, NULL);
208 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000211}
212#else
Dave Rodgman94a634d2023-10-10 12:59:29 +0100213#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
Dave Rodgman5b89c552023-10-10 14:59:02 +0100214#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000215#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
216
Dave Rodgman5b89c552023-10-10 14:59:02 +0100217#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000218
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000219#define SHA256_BLOCK_SIZE 64
220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200222{
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200224}
225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200227{
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200229 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200233}
234
Gilles Peskine449bd832023-01-11 14:50:10 +0100235void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
236 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200237{
238 *dst = *src;
239}
240
Paul Bakker5121ce52009-01-03 21:22:43 +0000241/*
242 * SHA-256 context setup
243 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100244int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000245{
Valerio Settia3f99592022-12-14 10:56:54 +0100246#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100248 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 }
Valerio Settia3f99592022-12-14 10:56:54 +0100250#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100252 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 }
Valerio Settia3f99592022-12-14 10:56:54 +0100254#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100256 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200258#endif
259
Paul Bakker5121ce52009-01-03 21:22:43 +0000260 ctx->total[0] = 0;
261 ctx->total[1] = 0;
262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100264#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000265 ctx->state[0] = 0x6A09E667;
266 ctx->state[1] = 0xBB67AE85;
267 ctx->state[2] = 0x3C6EF372;
268 ctx->state[3] = 0xA54FF53A;
269 ctx->state[4] = 0x510E527F;
270 ctx->state[5] = 0x9B05688C;
271 ctx->state[6] = 0x1F83D9AB;
272 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100273#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200275#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000276 ctx->state[0] = 0xC1059ED8;
277 ctx->state[1] = 0x367CD507;
278 ctx->state[2] = 0x3070DD17;
279 ctx->state[3] = 0xF70E5939;
280 ctx->state[4] = 0xFFC00B31;
281 ctx->state[5] = 0x68581511;
282 ctx->state[6] = 0x64F98FA7;
283 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200284#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 }
286
Valerio Settia3f99592022-12-14 10:56:54 +0100287#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100289#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000292}
293
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200294static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000295{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200296 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
297 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
298 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
299 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
300 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
301 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
302 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
303 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
304 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
305 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
306 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
307 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
308 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
309 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
310 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
311 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
312};
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
Dave Rodgman5b89c552023-10-10 14:59:02 +0100314#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
315 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000316
Dave Rodgman5b89c552023-10-10 14:59:02 +0100317#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000318# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
319# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
320#endif
321
322static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000324{
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
326 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000327
328 size_t processed = 0;
329
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000331 len >= SHA256_BLOCK_SIZE;
332 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 msg += SHA256_BLOCK_SIZE,
334 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000335 uint32x4_t tmp, abcd_prev;
336
337 uint32x4_t abcd_orig = abcd;
338 uint32x4_t efgh_orig = efgh;
339
Dave Rodgman9a36f4c2023-10-05 11:25:52 +0100340 uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
341 uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
342 uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
343 uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000344
345#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
346 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
348 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
349 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
350 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000351#endif
352
353 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000355 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
357 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000358
359 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000361 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
363 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000364
365 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000367 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
369 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000370
371 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000373 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
375 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000378 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
380 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000381 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
383 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000384
385 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
387 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
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
392 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
394 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000395 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
397 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000398
399 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
401 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000402 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
404 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000405 }
406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 abcd = vaddq_u32(abcd, abcd_orig);
408 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000409 }
410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 vst1q_u32(&ctx->state[0], abcd);
412 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000415}
416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
418 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000419{
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
421 SHA256_BLOCK_SIZE) ==
422 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000423}
424
Dave Rodgman5b89c552023-10-10 14:59:02 +0100425#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100426
Jerry Yu92fc5382023-02-16 11:17:11 +0800427#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800428#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800429#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800430#elif defined(__GNUC__)
431#pragma GCC pop_options
432#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800433#undef MBEDTLS_POP_TARGET_PRAGMA
434#endif
435
Dave Rodgman5b89c552023-10-10 14:59:02 +0100436#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000437#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
438#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
439#endif
440
441
Thomas Daubney297b0262024-07-16 17:21:43 +0100442#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
445#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
Gilles Peskine449bd832023-01-11 14:50:10 +0100447#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
448#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
Gilles Peskine449bd832023-01-11 14:50:10 +0100450#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
451#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
454#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200456#define R(t) \
457 ( \
458 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
459 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100460 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200463 do \
464 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
466 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200467 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
471 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200472{
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200474 uint32_t temp1, temp2, W[64];
475 uint32_t A[8];
476 } local;
477
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200478 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200481 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200483
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200484#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 for (i = 0; i < 64; i++) {
486 if (i < 16) {
487 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
488 } else {
489 R(i);
490 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
493 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200494
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200495 local.temp1 = local.A[7]; local.A[7] = local.A[6];
496 local.A[6] = local.A[5]; local.A[5] = local.A[4];
497 local.A[4] = local.A[3]; local.A[3] = local.A[2];
498 local.A[2] = local.A[1]; local.A[1] = local.A[0];
499 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200500 }
501#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 for (i = 0; i < 16; i++) {
503 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200504 }
505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 for (i = 0; i < 16; i += 8) {
507 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
508 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
509 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
510 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
511 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
512 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
513 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
514 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
515 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
516 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
517 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
518 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
519 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
520 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
521 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
522 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
523 }
524
525 for (i = 16; i < 64; i += 8) {
526 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
527 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
528 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
529 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
530 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
531 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
532 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
533 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
534 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
535 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
536 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
537 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
538 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
539 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
540 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
541 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200542 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200543#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200546 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100548
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200549 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000553}
Jaeden Amero041039f2018-02-19 15:28:08 +0000554
Thomas Daubney297b0262024-07-16 17:21:43 +0100555#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000556
Dave Rodgman5b89c552023-10-10 14:59:02 +0100557#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000558
559static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000561{
562 size_t processed = 0;
563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 while (len >= SHA256_BLOCK_SIZE) {
565 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
566 return 0;
567 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000568
569 data += SHA256_BLOCK_SIZE;
570 len -= SHA256_BLOCK_SIZE;
571
572 processed += SHA256_BLOCK_SIZE;
573 }
574
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000576}
577
Dave Rodgman5b89c552023-10-10 14:59:02 +0100578#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000579
580
Dave Rodgman5b89c552023-10-10 14:59:02 +0100581#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000584{
585 static int done = 0;
586 static int supported = 0;
587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000589 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000590 done = 1;
591 }
592
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000594}
595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
597 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000598{
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 if (mbedtls_a64_crypto_sha256_has_support()) {
600 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
601 } else {
602 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
603 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000604}
605
Thomas Daubneybfe1b672024-07-31 15:11:00 +0100606static int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000608{
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 if (mbedtls_a64_crypto_sha256_has_support()) {
610 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
611 } else {
612 return mbedtls_internal_sha256_process_c(ctx, data);
613 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000614}
615
Dave Rodgman5b89c552023-10-10 14:59:02 +0100616#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000617
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619/*
620 * SHA-256 process buffer
621 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100622int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
623 const unsigned char *input,
624 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000625{
Janos Follath24eed8d2019-11-22 13:21:35 +0000626 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000627 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000628 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if (ilen == 0) {
631 return 0;
632 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
634 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000635 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000636
Paul Bakker5c2364c2012-10-01 14:41:15 +0000637 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 ctx->total[0] &= 0xFFFFFFFF;
639
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000641 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 if (left && ilen >= fill) {
645 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100646
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
648 return ret;
649 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100650
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 input += fill;
652 ilen -= fill;
653 left = 0;
654 }
655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000657 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 mbedtls_internal_sha256_process_many(ctx, input, ilen);
659 if (processed < SHA256_BLOCK_SIZE) {
660 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
661 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100662
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000663 input += processed;
664 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 }
666
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 if (ilen > 0) {
668 memcpy((void *) (ctx->buffer + left), input, ilen);
669 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000672}
673
Paul Bakker5121ce52009-01-03 21:22:43 +0000674/*
675 * SHA-256 final digest
676 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100677int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
678 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000679{
Janos Follath24eed8d2019-11-22 13:21:35 +0000680 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200681 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000682 uint32_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100683 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200685 /*
686 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
687 */
688 used = ctx->total[0] & 0x3F;
689
690 ctx->buffer[used++] = 0x80;
691
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200693 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 memset(ctx->buffer + used, 0, 56 - used);
695 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200696 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100700 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200702
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200704 }
705
706 /*
707 * Add message length
708 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 high = (ctx->total[0] >> 29)
710 | (ctx->total[1] << 3);
711 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
714 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100717 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100719
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200720 /*
721 * Output final state
722 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
724 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
725 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
726 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
727 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
728 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
729 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200731#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100732 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200733#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 if (!truncated) {
735 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
736 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100737
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100738 ret = 0;
739
740exit:
741 mbedtls_sha256_free(ctx);
742 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000743}
744
745/*
746 * output = SHA-256( input buffer )
747 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100748int mbedtls_sha256(const unsigned char *input,
749 size_t ilen,
750 unsigned char *output,
751 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000752{
Janos Follath24eed8d2019-11-22 13:21:35 +0000753 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000755
Valerio Settia3f99592022-12-14 10:56:54 +0100756#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100758 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 }
Valerio Settia3f99592022-12-14 10:56:54 +0100760#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100762 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 }
Valerio Settia3f99592022-12-14 10:56:54 +0100764#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100766 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200768#endif
769
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100773 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100777 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100781 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100783
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100784exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100786
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000788}
789
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000791/*
792 * FIPS-180-2 test vectors
793 */
Valerio Settia3f99592022-12-14 10:56:54 +0100794static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000795{
796 { "abc" },
797 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
798 { "" }
799};
800
Valerio Settia3f99592022-12-14 10:56:54 +0100801static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000802{
803 3, 56, 1000
804};
805
Valerio Settia3f99592022-12-14 10:56:54 +0100806typedef const unsigned char (sha_test_sum_t)[32];
807
808/*
809 * SHA-224 test vectors
810 */
811#if defined(MBEDTLS_SHA224_C)
812static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000813{
Paul Bakker5121ce52009-01-03 21:22:43 +0000814 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
815 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
816 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
817 0xE3, 0x6C, 0x9D, 0xA7 },
818 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
819 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
820 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
821 0x52, 0x52, 0x25, 0x25 },
822 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
823 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
824 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100825 0x4E, 0xE7, 0xAD, 0x67 }
826};
827#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000828
Valerio Settia3f99592022-12-14 10:56:54 +0100829/*
830 * SHA-256 test vectors
831 */
832#if defined(MBEDTLS_SHA256_C)
833static sha_test_sum_t sha256_test_sum[] =
834{
Paul Bakker5121ce52009-01-03 21:22:43 +0000835 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
836 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
837 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
838 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
839 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
840 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
841 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
842 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
843 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
844 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
845 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
846 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
847};
Valerio Settia3f99592022-12-14 10:56:54 +0100848#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
850/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 * Checkup routine
852 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100853static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000854{
Valerio Settia3f99592022-12-14 10:56:54 +0100855 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500856 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200857 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000859
Valerio Settia3f99592022-12-14 10:56:54 +0100860#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100862#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100864#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100866#endif
867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 buf = mbedtls_calloc(1024, sizeof(unsigned char));
869 if (NULL == buf) {
870 if (verbose != 0) {
871 mbedtls_printf("Buffer allocation failed\n");
872 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500873
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500875 }
876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 for (i = 0; i < 3; i++) {
880 if (verbose != 0) {
881 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
882 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100885 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000887
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 if (i == 2) {
889 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 for (int j = 0; j < 1000; j++) {
892 ret = mbedtls_sha256_update(&ctx, buf, buflen);
893 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100894 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100896 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 } else {
899 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
900 sha_test_buflen[i]);
901 if (ret != 0) {
902 goto fail;
903 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100904 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100907 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100909
Paul Bakker5121ce52009-01-03 21:22:43 +0000910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100912 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100913 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100914 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000915
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 if (verbose != 0) {
917 mbedtls_printf("passed\n");
918 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000919 }
920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 if (verbose != 0) {
922 mbedtls_printf("\n");
923 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000924
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100925 goto exit;
926
927fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 if (verbose != 0) {
929 mbedtls_printf("failed\n");
930 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100931
Paul Bakker5b4af392014-06-26 12:09:34 +0200932exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 mbedtls_sha256_free(&ctx);
934 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200935
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000937}
938
Valerio Settia3f99592022-12-14 10:56:54 +0100939#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100940int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100941{
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100943}
944#endif /* MBEDTLS_SHA256_C */
945
946#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100947int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100948{
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100950}
951#endif /* MBEDTLS_SHA224_C */
952
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000954
Valerio Settia3f99592022-12-14 10:56:54 +0100955#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */