blob: 842b892cd516f718c8e09e8664cd43070f18aa68 [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)
Sergey Markelov4ed0fde2024-08-14 15:06:03 -0700155#ifndef WIN32_LEAN_AND_MEAN
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000156#define WIN32_LEAN_AND_MEAN
Sergey Markelov4ed0fde2024-08-14 15:06:03 -0700157#endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000158#include <Windows.h>
159#include <processthreadsapi.h>
160
Gilles Peskine449bd832023-01-11 14:50:10 +0100161static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000162{
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
164 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000165}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000166#elif defined(__unix__) && defined(SIG_SETMASK)
167/* Detection with SIGILL, setjmp() and longjmp() */
168#include <signal.h>
169#include <setjmp.h>
170
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000171static jmp_buf return_from_sigill;
172
173/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100174 * Armv8-A SHA256 support detection via SIGILL
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000175 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100176static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000177{
178 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000180}
181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000183{
184 struct sigaction old_action, new_action;
185
186 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 if (sigprocmask(0, NULL, &old_mask)) {
188 return 0;
189 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000192 new_action.sa_flags = 0;
193 new_action.sa_handler = sigill_handler;
194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000196
197 static int ret = 0;
198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000200 /* If this traps, we will return a second time from setjmp() with 1 */
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100201#if defined(MBEDTLS_ARCH_IS_ARM64)
Dave Rodgman78d78462023-10-10 09:53:44 +0100202 asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100203#else
Dave Rodgman78d78462023-10-10 09:53:44 +0100204 asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100205#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000206 ret = 1;
207 }
208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 sigaction(SIGILL, &old_action, NULL);
210 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000213}
214#else
Dave Rodgman94a634d2023-10-10 12:59:29 +0100215#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
Dave Rodgman5b89c552023-10-10 14:59:02 +0100216#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000217#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
218
Dave Rodgman5b89c552023-10-10 14:59:02 +0100219#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000220
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000221#define SHA256_BLOCK_SIZE 64
222
Gilles Peskine449bd832023-01-11 14:50:10 +0100223void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200224{
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200226}
227
Gilles Peskine449bd832023-01-11 14:50:10 +0100228void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200229{
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200231 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200233
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200235}
236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
238 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200239{
240 *dst = *src;
241}
242
Paul Bakker5121ce52009-01-03 21:22:43 +0000243/*
244 * SHA-256 context setup
245 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100246int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000247{
Valerio Settia3f99592022-12-14 10:56:54 +0100248#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100250 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 }
Valerio Settia3f99592022-12-14 10:56:54 +0100252#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100254 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 }
Valerio Settia3f99592022-12-14 10:56:54 +0100256#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100258 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200260#endif
261
Paul Bakker5121ce52009-01-03 21:22:43 +0000262 ctx->total[0] = 0;
263 ctx->total[1] = 0;
264
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100266#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 ctx->state[0] = 0x6A09E667;
268 ctx->state[1] = 0xBB67AE85;
269 ctx->state[2] = 0x3C6EF372;
270 ctx->state[3] = 0xA54FF53A;
271 ctx->state[4] = 0x510E527F;
272 ctx->state[5] = 0x9B05688C;
273 ctx->state[6] = 0x1F83D9AB;
274 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100275#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200277#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 ctx->state[0] = 0xC1059ED8;
279 ctx->state[1] = 0x367CD507;
280 ctx->state[2] = 0x3070DD17;
281 ctx->state[3] = 0xF70E5939;
282 ctx->state[4] = 0xFFC00B31;
283 ctx->state[5] = 0x68581511;
284 ctx->state[6] = 0x64F98FA7;
285 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200286#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 }
288
Valerio Settia3f99592022-12-14 10:56:54 +0100289#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100291#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000294}
295
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200296static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000297{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200298 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
299 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
300 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
301 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
302 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
303 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
304 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
305 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
306 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
307 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
308 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
309 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
310 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
311 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
312 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
313 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
314};
Paul Bakker5121ce52009-01-03 21:22:43 +0000315
Dave Rodgman5b89c552023-10-10 14:59:02 +0100316#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
317 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000318
Dave Rodgman5b89c552023-10-10 14:59:02 +0100319#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000320# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
321# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
322#endif
323
324static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000326{
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
328 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000329
330 size_t processed = 0;
331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000333 len >= SHA256_BLOCK_SIZE;
334 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 msg += SHA256_BLOCK_SIZE,
336 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000337 uint32x4_t tmp, abcd_prev;
338
339 uint32x4_t abcd_orig = abcd;
340 uint32x4_t efgh_orig = efgh;
341
Dave Rodgman9a36f4c2023-10-05 11:25:52 +0100342 uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
343 uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
344 uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
345 uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000346
347#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
348 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
350 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
351 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
352 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000353#endif
354
355 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000357 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
359 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000360
361 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000363 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
365 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000366
367 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000369 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
371 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000372
373 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000375 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
377 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000378
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000380 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
382 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
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 t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
389 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000390 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
392 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000393
394 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
396 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
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 + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
403 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
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
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 abcd = vaddq_u32(abcd, abcd_orig);
410 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000411 }
412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 vst1q_u32(&ctx->state[0], abcd);
414 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000417}
418
Thomas Daubneyeb97f2a2024-08-01 12:19:31 +0100419static int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
Thomas Daubney15129192024-08-01 13:06:01 +0100420 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000421{
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
423 SHA256_BLOCK_SIZE) ==
424 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000425}
426
Dave Rodgman5b89c552023-10-10 14:59:02 +0100427#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100428
Jerry Yu92fc5382023-02-16 11:17:11 +0800429#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800430#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800431#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800432#elif defined(__GNUC__)
433#pragma GCC pop_options
434#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800435#undef MBEDTLS_POP_TARGET_PRAGMA
436#endif
437
Dave Rodgman5b89c552023-10-10 14:59:02 +0100438#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000439#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
440#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
441#endif
442
443
Thomas Daubney297b0262024-07-16 17:21:43 +0100444#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
447#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
450#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
453#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
456#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000457
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200458#define R(t) \
459 ( \
460 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
461 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100462 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200465 do \
466 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
468 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200469 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
Thomas Daubneyeb97f2a2024-08-01 12:19:31 +0100472static int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
Thomas Daubney15129192024-08-01 13:06:01 +0100473 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200474{
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200476 uint32_t temp1, temp2, W[64];
477 uint32_t A[8];
478 } local;
479
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200480 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000481
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200483 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200485
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200486#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 for (i = 0; i < 64; i++) {
488 if (i < 16) {
489 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
490 } else {
491 R(i);
492 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
495 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200496
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200497 local.temp1 = local.A[7]; local.A[7] = local.A[6];
498 local.A[6] = local.A[5]; local.A[5] = local.A[4];
499 local.A[4] = local.A[3]; local.A[3] = local.A[2];
500 local.A[2] = local.A[1]; local.A[1] = local.A[0];
501 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200502 }
503#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 for (i = 0; i < 16; i++) {
505 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200506 }
507
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 for (i = 0; i < 16; i += 8) {
509 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
510 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
511 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
512 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
513 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
514 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
515 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
516 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
517 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
518 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
519 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
520 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
521 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
522 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
523 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
524 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
525 }
526
527 for (i = 16; i < 64; i += 8) {
528 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
529 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
530 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
531 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
532 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
533 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
534 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
535 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
536 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
537 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
538 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
539 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
540 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
541 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
542 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
543 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200544 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200545#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200548 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100550
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200551 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000555}
Jaeden Amero041039f2018-02-19 15:28:08 +0000556
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000557static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000559{
560 size_t processed = 0;
561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 while (len >= SHA256_BLOCK_SIZE) {
563 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
564 return 0;
565 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000566
567 data += SHA256_BLOCK_SIZE;
568 len -= SHA256_BLOCK_SIZE;
569
570 processed += SHA256_BLOCK_SIZE;
571 }
572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000574}
575
Dave Rodgman5b89c552023-10-10 14:59:02 +0100576#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000577
578
Dave Rodgman5b89c552023-10-10 14:59:02 +0100579#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000580
Gilles Peskine449bd832023-01-11 14:50:10 +0100581static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000582{
583 static int done = 0;
584 static int supported = 0;
585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000587 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000588 done = 1;
589 }
590
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000592}
593
Gilles Peskine449bd832023-01-11 14:50:10 +0100594static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
595 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000596{
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 if (mbedtls_a64_crypto_sha256_has_support()) {
598 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
599 } else {
600 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
601 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000602}
603
Thomas Daubneybfe1b672024-07-31 15:11:00 +0100604static int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
Thomas Daubney15129192024-08-01 13:06:01 +0100605 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000606{
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 if (mbedtls_a64_crypto_sha256_has_support()) {
608 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
609 } else {
610 return mbedtls_internal_sha256_process_c(ctx, data);
611 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000612}
613
Dave Rodgman5b89c552023-10-10 14:59:02 +0100614#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000615
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
617/*
618 * SHA-256 process buffer
619 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100620int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
621 const unsigned char *input,
622 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000623{
Janos Follath24eed8d2019-11-22 13:21:35 +0000624 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000625 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000626 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 if (ilen == 0) {
629 return 0;
630 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000631
632 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000633 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
Paul Bakker5c2364c2012-10-01 14:41:15 +0000635 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 ctx->total[0] &= 0xFFFFFFFF;
637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000639 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 if (left && ilen >= fill) {
643 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100644
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
646 return ret;
647 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100648
Paul Bakker5121ce52009-01-03 21:22:43 +0000649 input += fill;
650 ilen -= fill;
651 left = 0;
652 }
653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000655 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 mbedtls_internal_sha256_process_many(ctx, input, ilen);
657 if (processed < SHA256_BLOCK_SIZE) {
658 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
659 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100660
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000661 input += processed;
662 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 }
664
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 if (ilen > 0) {
666 memcpy((void *) (ctx->buffer + left), input, ilen);
667 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000670}
671
Paul Bakker5121ce52009-01-03 21:22:43 +0000672/*
673 * SHA-256 final digest
674 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100675int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
676 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000677{
Janos Follath24eed8d2019-11-22 13:21:35 +0000678 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200679 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000680 uint32_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100681 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200683 /*
684 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
685 */
686 used = ctx->total[0] & 0x3F;
687
688 ctx->buffer[used++] = 0x80;
689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200691 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 memset(ctx->buffer + used, 0, 56 - used);
693 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200694 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100698 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200700
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200702 }
703
704 /*
705 * Add message length
706 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 high = (ctx->total[0] >> 29)
708 | (ctx->total[1] << 3);
709 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
712 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100715 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100717
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200718 /*
719 * Output final state
720 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
722 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
723 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
724 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
725 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
726 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
727 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000728
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200729#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100730 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200731#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 if (!truncated) {
733 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
734 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100735
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100736 ret = 0;
737
738exit:
739 mbedtls_sha256_free(ctx);
740 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000741}
742
743/*
744 * output = SHA-256( input buffer )
745 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746int mbedtls_sha256(const unsigned char *input,
747 size_t ilen,
748 unsigned char *output,
749 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000750{
Janos Follath24eed8d2019-11-22 13:21:35 +0000751 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200752 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
Valerio Settia3f99592022-12-14 10:56:54 +0100754#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100756 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 }
Valerio Settia3f99592022-12-14 10:56:54 +0100758#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100760 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 }
Valerio Settia3f99592022-12-14 10:56:54 +0100762#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100764 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200766#endif
767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100769
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100771 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100775 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100777
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100779 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100781
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100782exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100784
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000786}
787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000789/*
790 * FIPS-180-2 test vectors
791 */
Valerio Settia3f99592022-12-14 10:56:54 +0100792static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000793{
794 { "abc" },
795 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
796 { "" }
797};
798
Valerio Settia3f99592022-12-14 10:56:54 +0100799static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000800{
801 3, 56, 1000
802};
803
Valerio Settia3f99592022-12-14 10:56:54 +0100804typedef const unsigned char (sha_test_sum_t)[32];
805
806/*
807 * SHA-224 test vectors
808 */
809#if defined(MBEDTLS_SHA224_C)
810static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000811{
Paul Bakker5121ce52009-01-03 21:22:43 +0000812 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
813 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
814 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
815 0xE3, 0x6C, 0x9D, 0xA7 },
816 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
817 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
818 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
819 0x52, 0x52, 0x25, 0x25 },
820 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
821 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
822 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100823 0x4E, 0xE7, 0xAD, 0x67 }
824};
825#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
Valerio Settia3f99592022-12-14 10:56:54 +0100827/*
828 * SHA-256 test vectors
829 */
830#if defined(MBEDTLS_SHA256_C)
831static sha_test_sum_t sha256_test_sum[] =
832{
Paul Bakker5121ce52009-01-03 21:22:43 +0000833 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
834 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
835 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
836 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
837 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
838 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
839 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
840 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
841 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
842 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
843 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
844 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
845};
Valerio Settia3f99592022-12-14 10:56:54 +0100846#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000847
848/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000849 * Checkup routine
850 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100851static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000852{
Valerio Settia3f99592022-12-14 10:56:54 +0100853 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500854 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200855 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000857
Valerio Settia3f99592022-12-14 10:56:54 +0100858#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100860#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100862#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100864#endif
865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 buf = mbedtls_calloc(1024, sizeof(unsigned char));
867 if (NULL == buf) {
868 if (verbose != 0) {
869 mbedtls_printf("Buffer allocation failed\n");
870 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500873 }
874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 for (i = 0; i < 3; i++) {
878 if (verbose != 0) {
879 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
880 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100883 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000885
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 if (i == 2) {
887 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 for (int j = 0; j < 1000; j++) {
890 ret = mbedtls_sha256_update(&ctx, buf, buflen);
891 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100892 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100894 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 } else {
897 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
898 sha_test_buflen[i]);
899 if (ret != 0) {
900 goto fail;
901 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100902 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100905 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100907
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100910 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100911 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100912 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 if (verbose != 0) {
915 mbedtls_printf("passed\n");
916 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 }
918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if (verbose != 0) {
920 mbedtls_printf("\n");
921 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000922
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100923 goto exit;
924
925fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 if (verbose != 0) {
927 mbedtls_printf("failed\n");
928 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100929
Paul Bakker5b4af392014-06-26 12:09:34 +0200930exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 mbedtls_sha256_free(&ctx);
932 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000935}
936
Valerio Settia3f99592022-12-14 10:56:54 +0100937#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100938int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100939{
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100941}
942#endif /* MBEDTLS_SHA256_C */
943
944#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100945int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100946{
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100948}
949#endif /* MBEDTLS_SHA224_C */
950
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000952
Valerio Settia3f99592022-12-14 10:56:54 +0100953#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */