blob: 159acccaeb38a9167195df23a22936c8b2ea7e5a [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.kale2a0a6282024-04-02 18:10:39 +053047#if !defined(_GNU_SOURCE)
Dave Rodgman7ed619d2023-10-05 09:39:56 +010048#define _GNU_SOURCE
nilesh.kale2a0a6282024-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 Markelov68c0e3d2024-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 Markelov68c0e3d2024-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
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200221#if !defined(MBEDTLS_SHA256_ALT)
222
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000223#define SHA256_BLOCK_SIZE 64
224
Gilles Peskine449bd832023-01-11 14:50:10 +0100225void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200226{
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200228}
229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200231{
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200233 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200237}
238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
240 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200241{
242 *dst = *src;
243}
244
Paul Bakker5121ce52009-01-03 21:22:43 +0000245/*
246 * SHA-256 context setup
247 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100248int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000249{
Valerio Settia3f99592022-12-14 10:56:54 +0100250#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 if (is224 != 0 && is224 != 1) {
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#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100256 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 }
Valerio Settia3f99592022-12-14 10:56:54 +0100258#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100260 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200262#endif
263
Paul Bakker5121ce52009-01-03 21:22:43 +0000264 ctx->total[0] = 0;
265 ctx->total[1] = 0;
266
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100268#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000269 ctx->state[0] = 0x6A09E667;
270 ctx->state[1] = 0xBB67AE85;
271 ctx->state[2] = 0x3C6EF372;
272 ctx->state[3] = 0xA54FF53A;
273 ctx->state[4] = 0x510E527F;
274 ctx->state[5] = 0x9B05688C;
275 ctx->state[6] = 0x1F83D9AB;
276 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100277#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200279#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 ctx->state[0] = 0xC1059ED8;
281 ctx->state[1] = 0x367CD507;
282 ctx->state[2] = 0x3070DD17;
283 ctx->state[3] = 0xF70E5939;
284 ctx->state[4] = 0xFFC00B31;
285 ctx->state[5] = 0x68581511;
286 ctx->state[6] = 0x64F98FA7;
287 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200288#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 }
290
Valerio Settia3f99592022-12-14 10:56:54 +0100291#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100293#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100294
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000296}
297
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200299static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000300{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200301 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
302 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
303 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
304 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
305 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
306 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
307 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
308 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
309 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
310 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
311 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
312 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
313 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
314 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
315 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
316 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
317};
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000319#endif
320
Dave Rodgman5b89c552023-10-10 14:59:02 +0100321#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
322 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000323
Dave Rodgman5b89c552023-10-10 14:59:02 +0100324#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000325# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
326# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
327#endif
328
329static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000331{
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
333 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334
335 size_t processed = 0;
336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000338 len >= SHA256_BLOCK_SIZE;
339 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 msg += SHA256_BLOCK_SIZE,
341 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000342 uint32x4_t tmp, abcd_prev;
343
344 uint32x4_t abcd_orig = abcd;
345 uint32x4_t efgh_orig = efgh;
346
Dave Rodgman9a36f4c2023-10-05 11:25:52 +0100347 uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
348 uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
349 uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
350 uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000351
352#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
353 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
355 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
356 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
357 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000358#endif
359
360 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000362 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
364 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000365
366 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000368 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
370 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000371
372 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000374 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
376 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000377
378 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000380 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
382 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000385 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
387 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
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 + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
394 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
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 + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
401 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
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 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
408 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000409 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
411 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000412 }
413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 abcd = vaddq_u32(abcd, abcd_orig);
415 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000416 }
417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 vst1q_u32(&ctx->state[0], abcd);
419 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000422}
423
Dave Rodgman5b89c552023-10-10 14:59:02 +0100424#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100425/*
Dave Rodgman4fd868e2023-10-12 09:09:42 +0100426 * This function is for internal use only if we are building both C and Armv8-A
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100427 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
428 */
429static
430#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100431int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
432 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000433{
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
435 SHA256_BLOCK_SIZE) ==
436 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000437}
438
Dave Rodgman5b89c552023-10-10 14:59:02 +0100439#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100440
Jerry Yu92fc5382023-02-16 11:17:11 +0800441#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800442#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800443#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800444#elif defined(__GNUC__)
445#pragma GCC pop_options
446#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800447#undef MBEDTLS_POP_TARGET_PRAGMA
448#endif
449
Dave Rodgman5b89c552023-10-10 14:59:02 +0100450#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000451#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
452#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
453#endif
454
455
456#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
Dave Rodgman5b89c552023-10-10 14:59:02 +0100457 !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000458
Gilles Peskine449bd832023-01-11 14:50:10 +0100459#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
460#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
463#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
466#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
469#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200471#define R(t) \
472 ( \
473 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
474 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100475 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200478 do \
479 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
481 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200482 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
Dave Rodgman5b89c552023-10-10 14:59:02 +0100485#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100486/*
Dave Rodgman94a634d2023-10-10 12:59:29 +0100487 * This function is for internal use only if we are building both C and Armv8
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100488 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
489 */
490static
491#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100492int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
493 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200494{
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200496 uint32_t temp1, temp2, W[64];
497 uint32_t A[8];
498 } local;
499
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200500 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200503 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200505
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200506#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 for (i = 0; i < 64; i++) {
508 if (i < 16) {
509 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
510 } else {
511 R(i);
512 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200513
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
515 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200516
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200517 local.temp1 = local.A[7]; local.A[7] = local.A[6];
518 local.A[6] = local.A[5]; local.A[5] = local.A[4];
519 local.A[4] = local.A[3]; local.A[3] = local.A[2];
520 local.A[2] = local.A[1]; local.A[1] = local.A[0];
521 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200522 }
523#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 for (i = 0; i < 16; i++) {
525 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200526 }
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 for (i = 0; i < 16; i += 8) {
529 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
530 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
531 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
532 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
533 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
534 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
535 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
536 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
537 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
538 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
539 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
540 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
541 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
542 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
543 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
544 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
545 }
546
547 for (i = 16; i < 64; i += 8) {
548 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
549 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
550 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
551 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
552 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
553 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
554 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
555 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
556 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
557 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
558 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
559 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
560 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
561 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
562 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
563 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200564 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200565#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200568 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100570
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200571 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100573
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000575}
Jaeden Amero041039f2018-02-19 15:28:08 +0000576
Dave Rodgman5b89c552023-10-10 14:59:02 +0100577#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000578
579
Dave Rodgman5b89c552023-10-10 14:59:02 +0100580#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000581
582static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000584{
585 size_t processed = 0;
586
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 while (len >= SHA256_BLOCK_SIZE) {
588 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
589 return 0;
590 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000591
592 data += SHA256_BLOCK_SIZE;
593 len -= SHA256_BLOCK_SIZE;
594
595 processed += SHA256_BLOCK_SIZE;
596 }
597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000599}
600
Dave Rodgman5b89c552023-10-10 14:59:02 +0100601#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000602
603
Dave Rodgman5b89c552023-10-10 14:59:02 +0100604#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000607{
608 static int done = 0;
609 static int supported = 0;
610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000612 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000613 done = 1;
614 }
615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000617}
618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
620 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000621{
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 if (mbedtls_a64_crypto_sha256_has_support()) {
623 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
624 } else {
625 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
626 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000627}
628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
630 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000631{
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 if (mbedtls_a64_crypto_sha256_has_support()) {
633 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
634 } else {
635 return mbedtls_internal_sha256_process_c(ctx, data);
636 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000637}
638
Dave Rodgman5b89c552023-10-10 14:59:02 +0100639#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000640
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
642/*
643 * SHA-256 process buffer
644 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100645int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
646 const unsigned char *input,
647 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000648{
Janos Follath24eed8d2019-11-22 13:21:35 +0000649 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000650 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000651 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 if (ilen == 0) {
654 return 0;
655 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
657 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000658 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
Paul Bakker5c2364c2012-10-01 14:41:15 +0000660 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 ctx->total[0] &= 0xFFFFFFFF;
662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 if (left && ilen >= fill) {
668 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100669
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
671 return ret;
672 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100673
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 input += fill;
675 ilen -= fill;
676 left = 0;
677 }
678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000680 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 mbedtls_internal_sha256_process_many(ctx, input, ilen);
682 if (processed < SHA256_BLOCK_SIZE) {
683 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
684 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100685
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000686 input += processed;
687 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 }
689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 if (ilen > 0) {
691 memcpy((void *) (ctx->buffer + left), input, ilen);
692 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000695}
696
Paul Bakker5121ce52009-01-03 21:22:43 +0000697/*
698 * SHA-256 final digest
699 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100700int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
701 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000702{
Janos Follath24eed8d2019-11-22 13:21:35 +0000703 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200704 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000705 uint32_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100706 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000707
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200708 /*
709 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
710 */
711 used = ctx->total[0] & 0x3F;
712
713 ctx->buffer[used++] = 0x80;
714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200716 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 memset(ctx->buffer + used, 0, 56 - used);
718 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200719 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100723 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200727 }
728
729 /*
730 * Add message length
731 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 high = (ctx->total[0] >> 29)
733 | (ctx->total[1] << 3);
734 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
737 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100740 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100742
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200743 /*
744 * Output final state
745 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
747 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
748 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
749 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
750 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
751 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
752 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200754#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100755 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200756#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if (!truncated) {
758 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
759 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100760
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100761 ret = 0;
762
763exit:
764 mbedtls_sha256_free(ctx);
765 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000766}
767
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200769
Paul Bakker5121ce52009-01-03 21:22:43 +0000770/*
771 * output = SHA-256( input buffer )
772 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100773int mbedtls_sha256(const unsigned char *input,
774 size_t ilen,
775 unsigned char *output,
776 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000777{
Janos Follath24eed8d2019-11-22 13:21:35 +0000778 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
Valerio Settia3f99592022-12-14 10:56:54 +0100781#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100783 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 }
Valerio Settia3f99592022-12-14 10:56:54 +0100785#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100787 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 }
Valerio Settia3f99592022-12-14 10:56:54 +0100789#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100791 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200793#endif
794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100798 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100800
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100802 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100806 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100808
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100809exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100811
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000813}
814
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000816/*
817 * FIPS-180-2 test vectors
818 */
Valerio Settia3f99592022-12-14 10:56:54 +0100819static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000820{
821 { "abc" },
822 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
823 { "" }
824};
825
Valerio Settia3f99592022-12-14 10:56:54 +0100826static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000827{
828 3, 56, 1000
829};
830
Valerio Settia3f99592022-12-14 10:56:54 +0100831typedef const unsigned char (sha_test_sum_t)[32];
832
833/*
834 * SHA-224 test vectors
835 */
836#if defined(MBEDTLS_SHA224_C)
837static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000838{
Paul Bakker5121ce52009-01-03 21:22:43 +0000839 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
840 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
841 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
842 0xE3, 0x6C, 0x9D, 0xA7 },
843 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
844 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
845 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
846 0x52, 0x52, 0x25, 0x25 },
847 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
848 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
849 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100850 0x4E, 0xE7, 0xAD, 0x67 }
851};
852#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000853
Valerio Settia3f99592022-12-14 10:56:54 +0100854/*
855 * SHA-256 test vectors
856 */
857#if defined(MBEDTLS_SHA256_C)
858static sha_test_sum_t sha256_test_sum[] =
859{
Paul Bakker5121ce52009-01-03 21:22:43 +0000860 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
861 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
862 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
863 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
864 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
865 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
866 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
867 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
868 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
869 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
870 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
871 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
872};
Valerio Settia3f99592022-12-14 10:56:54 +0100873#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000874
875/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000876 * Checkup routine
877 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100878static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000879{
Valerio Settia3f99592022-12-14 10:56:54 +0100880 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500881 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200882 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000884
Valerio Settia3f99592022-12-14 10:56:54 +0100885#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100887#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100889#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100891#endif
892
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 buf = mbedtls_calloc(1024, sizeof(unsigned char));
894 if (NULL == buf) {
895 if (verbose != 0) {
896 mbedtls_printf("Buffer allocation failed\n");
897 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500900 }
901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 for (i = 0; i < 3; i++) {
905 if (verbose != 0) {
906 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
907 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100910 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 if (i == 2) {
914 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000915
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 for (int j = 0; j < 1000; j++) {
917 ret = mbedtls_sha256_update(&ctx, buf, buflen);
918 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100919 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100921 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100922
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 } else {
924 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
925 sha_test_buflen[i]);
926 if (ret != 0) {
927 goto fail;
928 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100929 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100932 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100934
Paul Bakker5121ce52009-01-03 21:22:43 +0000935
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100937 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100938 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100939 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 if (verbose != 0) {
942 mbedtls_printf("passed\n");
943 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 }
945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 if (verbose != 0) {
947 mbedtls_printf("\n");
948 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000949
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100950 goto exit;
951
952fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 if (verbose != 0) {
954 mbedtls_printf("failed\n");
955 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100956
Paul Bakker5b4af392014-06-26 12:09:34 +0200957exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 mbedtls_sha256_free(&ctx);
959 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200960
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000962}
963
Valerio Settia3f99592022-12-14 10:56:54 +0100964#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100965int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100966{
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100968}
969#endif /* MBEDTLS_SHA256_C */
970
971#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100972int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100973{
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100975}
976#endif /* MBEDTLS_SHA224_C */
977
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000979
Valerio Settia3f99592022-12-14 10:56:54 +0100980#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */