blob: ed47c7c51053ef452e5e553e162858d476460741 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Jerry Yua135dee2023-02-16 16:56:22 +080025#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
Jerry Yu6f86c192023-03-13 11:03:40 +080026 defined(__clang__) && __clang_major__ >= 4
Jerry Yua135dee2023-02-16 16:56:22 +080027/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
28 *
Jerry Yufc2e1282023-02-27 11:16:56 +080029 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
30 * these are normally only enabled by the -march option on the command line.
31 * By defining the macros ourselves we gain access to those declarations without
32 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080033 *
Dave Rodgmana0f10da2023-09-05 11:43:17 +010034 * `arm_neon.h` is included by common.h, so we put these defines
Jerry Yufc2e1282023-02-27 11:16:56 +080035 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080036 */
37#define __ARM_FEATURE_CRYPTO 1
Jerry Yuae129c32023-03-03 15:55:56 +080038/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
39 *
Jerry Yu490bf082023-03-06 15:21:44 +080040 * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
41 * for older compilers.
Jerry Yuae129c32023-03-03 15:55:56 +080042 */
43#define __ARM_FEATURE_SHA2 1
Dave Rodgmandb6ab242023-03-14 16:03:57 +000044#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
Jerry Yu490bf082023-03-06 15:21:44 +080045#endif
Jerry Yua135dee2023-02-16 16:56:22 +080046
Gilles Peskinedb09ef62020-06-03 01:43:33 +020047#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000048
Valerio Settia3f99592022-12-14 10:56:54 +010049#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000050
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000051#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050052#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000053#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000054
Rich Evans00ab4702015-02-06 13:43:58 +000055#include <string.h>
56
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000057#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010058
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000059#if defined(__aarch64__)
Jerry Yu08933d32023-04-27 18:28:00 +080060
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000061# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010062 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Jerry Yu08933d32023-04-27 18:28:00 +080063
Jerry Yu35f2b262023-02-15 11:35:55 +080064/* *INDENT-OFF* */
Jerry Yu6b00f5a2023-05-04 16:30:21 +080065
Dave Rodgmana0f10da2023-09-05 11:43:17 +010066# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
Jerry Yu6b00f5a2023-05-04 16:30:21 +080067# error "Target does not support NEON instructions"
68# endif
69
Dave Rodgmandb6ab242023-03-14 16:03:57 +000070# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
Jerry Yub1d06bb2023-05-05 14:05:07 +080071# if defined(__ARMCOMPILER_VERSION)
72# if __ARMCOMPILER_VERSION <= 6090000
73# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
74# endif
75# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
76# define MBEDTLS_POP_TARGET_PRAGMA
77# elif defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080078# if __clang_major__ < 4
79# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080080# endif
Jerry Yub1d06bb2023-05-05 14:05:07 +080081# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080082# define MBEDTLS_POP_TARGET_PRAGMA
83# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +000084 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
85 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +080086 */
87# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080088# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
89# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080090# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080091# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080092# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080093# endif
94# else
95# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
96# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080097# endif
98/* *INDENT-ON* */
Jerry Yu08933d32023-04-27 18:28:00 +080099
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000100# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000101# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
102# if defined(__unix__)
103# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100104/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000105# include <sys/auxv.h>
106# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100107/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000108# include <signal.h>
109# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000110# endif
Dave Rodgman0a487172023-09-15 11:52:06 +0100111#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000112# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
113# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
114#endif
115
116#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
117/*
118 * Capability detection code comes early, so we can disable
119 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
120 */
121#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100122static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000123{
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000125}
126#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100127static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000128{
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000130}
Dave Rodgman0a487172023-09-15 11:52:06 +0100131#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000132#define WIN32_LEAN_AND_MEAN
133#include <Windows.h>
134#include <processthreadsapi.h>
135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000137{
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
139 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000140}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000141#elif defined(__unix__) && defined(SIG_SETMASK)
142/* Detection with SIGILL, setjmp() and longjmp() */
143#include <signal.h>
144#include <setjmp.h>
145
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000146static jmp_buf return_from_sigill;
147
148/*
149 * A64 SHA256 support detection via SIGILL
150 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100151static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000152{
153 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000155}
156
Gilles Peskine449bd832023-01-11 14:50:10 +0100157static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000158{
159 struct sigaction old_action, new_action;
160
161 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 if (sigprocmask(0, NULL, &old_mask)) {
163 return 0;
164 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000165
Gilles Peskine449bd832023-01-11 14:50:10 +0100166 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000167 new_action.sa_flags = 0;
168 new_action.sa_handler = sigill_handler;
169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000171
172 static int ret = 0;
173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000175 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000177 ret = 1;
178 }
179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 sigaction(SIGILL, &old_action, NULL);
181 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000184}
185#else
186#warning "No mechanism to detect A64_CRYPTO found, using C code only"
187#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
188#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
189
190#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
191
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200192#if !defined(MBEDTLS_SHA256_ALT)
193
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000194#define SHA256_BLOCK_SIZE 64
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200197{
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200199}
200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200202{
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200204 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200208}
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
211 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200212{
213 *dst = *src;
214}
215
Paul Bakker5121ce52009-01-03 21:22:43 +0000216/*
217 * SHA-256 context setup
218 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100219int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000220{
Valerio Settia3f99592022-12-14 10:56:54 +0100221#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100223 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 }
Valerio Settia3f99592022-12-14 10:56:54 +0100225#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100227 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 }
Valerio Settia3f99592022-12-14 10:56:54 +0100229#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100231 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200233#endif
234
Paul Bakker5121ce52009-01-03 21:22:43 +0000235 ctx->total[0] = 0;
236 ctx->total[1] = 0;
237
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100239#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 ctx->state[0] = 0x6A09E667;
241 ctx->state[1] = 0xBB67AE85;
242 ctx->state[2] = 0x3C6EF372;
243 ctx->state[3] = 0xA54FF53A;
244 ctx->state[4] = 0x510E527F;
245 ctx->state[5] = 0x9B05688C;
246 ctx->state[6] = 0x1F83D9AB;
247 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100248#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200250#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 ctx->state[0] = 0xC1059ED8;
252 ctx->state[1] = 0x367CD507;
253 ctx->state[2] = 0x3070DD17;
254 ctx->state[3] = 0xF70E5939;
255 ctx->state[4] = 0xFFC00B31;
256 ctx->state[5] = 0x68581511;
257 ctx->state[6] = 0x64F98FA7;
258 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200259#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000260 }
261
Valerio Settia3f99592022-12-14 10:56:54 +0100262#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000263 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100264#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100265
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000267}
268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200270static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000271{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200272 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
273 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
274 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
275 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
276 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
277 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
278 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
279 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
280 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
281 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
282 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
283 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
284 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
285 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
286 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
287 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
288};
Paul Bakker5121ce52009-01-03 21:22:43 +0000289
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000290#endif
291
292#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
293 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
294
295#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
296# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
297# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
298#endif
299
300static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000302{
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
304 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000305
306 size_t processed = 0;
307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000309 len >= SHA256_BLOCK_SIZE;
310 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 msg += SHA256_BLOCK_SIZE,
312 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000313 uint32x4_t tmp, abcd_prev;
314
315 uint32x4_t abcd_orig = abcd;
316 uint32x4_t efgh_orig = efgh;
317
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
319 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
320 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
321 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000322
323#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
324 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
326 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
327 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
328 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000329#endif
330
331 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000333 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
335 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000336
337 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000339 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
341 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000342
343 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000345 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
347 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000348
349 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000351 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
353 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000356 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
358 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000359 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
361 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000362
363 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
365 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000366 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
368 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000369
370 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
372 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000373 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
375 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000376
377 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
379 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 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 }
384
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 abcd = vaddq_u32(abcd, abcd_orig);
386 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000387 }
388
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 vst1q_u32(&ctx->state[0], abcd);
390 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000393}
394
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100395#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
396/*
397 * This function is for internal use only if we are building both C and A64
398 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
399 */
400static
401#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100402int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
403 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000404{
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
406 SHA256_BLOCK_SIZE) ==
407 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000408}
409
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100410#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
411
Jerry Yu92fc5382023-02-16 11:17:11 +0800412#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800413#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800414#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800415#elif defined(__GNUC__)
416#pragma GCC pop_options
417#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800418#undef MBEDTLS_POP_TARGET_PRAGMA
419#endif
420
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000421#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
422#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
423#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
424#endif
425
426
427#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
428 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
429
Gilles Peskine449bd832023-01-11 14:50:10 +0100430#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
431#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
434#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
437#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
Gilles Peskine449bd832023-01-11 14:50:10 +0100439#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
440#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200442#define R(t) \
443 ( \
444 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
445 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100446 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200449 do \
450 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
452 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200453 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100456#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
457/*
458 * This function is for internal use only if we are building both C and A64
459 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
460 */
461static
462#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100463int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
464 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200465{
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200467 uint32_t temp1, temp2, W[64];
468 uint32_t A[8];
469 } local;
470
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200471 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200474 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200476
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200477#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 for (i = 0; i < 64; i++) {
479 if (i < 16) {
480 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
481 } else {
482 R(i);
483 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
486 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200487
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200488 local.temp1 = local.A[7]; local.A[7] = local.A[6];
489 local.A[6] = local.A[5]; local.A[5] = local.A[4];
490 local.A[4] = local.A[3]; local.A[3] = local.A[2];
491 local.A[2] = local.A[1]; local.A[1] = local.A[0];
492 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200493 }
494#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 for (i = 0; i < 16; i++) {
496 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200497 }
498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 for (i = 0; i < 16; i += 8) {
500 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
501 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
502 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
503 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
504 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
505 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
506 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
507 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
508 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
509 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
510 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
511 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
512 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
513 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
514 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
515 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
516 }
517
518 for (i = 16; i < 64; i += 8) {
519 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
520 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
521 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
522 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
523 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
524 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
525 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
526 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
527 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
528 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
529 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
530 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
531 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
532 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
533 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
534 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200535 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200536#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200539 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100541
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200542 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000546}
Jaeden Amero041039f2018-02-19 15:28:08 +0000547
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000548#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
549
550
551#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
552
553static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000555{
556 size_t processed = 0;
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 while (len >= SHA256_BLOCK_SIZE) {
559 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
560 return 0;
561 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000562
563 data += SHA256_BLOCK_SIZE;
564 len -= SHA256_BLOCK_SIZE;
565
566 processed += SHA256_BLOCK_SIZE;
567 }
568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000570}
571
572#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
573
574
575#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000578{
579 static int done = 0;
580 static int supported = 0;
581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000583 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000584 done = 1;
585 }
586
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000588}
589
Gilles Peskine449bd832023-01-11 14:50:10 +0100590static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
591 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000592{
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 if (mbedtls_a64_crypto_sha256_has_support()) {
594 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
595 } else {
596 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
597 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000598}
599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
601 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000602{
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 if (mbedtls_a64_crypto_sha256_has_support()) {
604 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
605 } else {
606 return mbedtls_internal_sha256_process_c(ctx, data);
607 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000608}
609
610#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
611
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613/*
614 * SHA-256 process buffer
615 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100616int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
617 const unsigned char *input,
618 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000619{
Janos Follath24eed8d2019-11-22 13:21:35 +0000620 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000621 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000622 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 if (ilen == 0) {
625 return 0;
626 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
628 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000629 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
Paul Bakker5c2364c2012-10-01 14:41:15 +0000631 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 ctx->total[0] &= 0xFFFFFFFF;
633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (left && ilen >= fill) {
639 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
642 return ret;
643 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100644
Paul Bakker5121ce52009-01-03 21:22:43 +0000645 input += fill;
646 ilen -= fill;
647 left = 0;
648 }
649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000651 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 mbedtls_internal_sha256_process_many(ctx, input, ilen);
653 if (processed < SHA256_BLOCK_SIZE) {
654 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
655 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100656
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000657 input += processed;
658 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000659 }
660
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 if (ilen > 0) {
662 memcpy((void *) (ctx->buffer + left), input, ilen);
663 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100664
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000666}
667
Paul Bakker5121ce52009-01-03 21:22:43 +0000668/*
669 * SHA-256 final digest
670 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100671int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
672 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000673{
Janos Follath24eed8d2019-11-22 13:21:35 +0000674 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200675 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000676 uint32_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100677 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200679 /*
680 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
681 */
682 used = ctx->total[0] & 0x3F;
683
684 ctx->buffer[used++] = 0x80;
685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200687 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 memset(ctx->buffer + used, 0, 56 - used);
689 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200690 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100694 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200698 }
699
700 /*
701 * Add message length
702 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 high = (ctx->total[0] >> 29)
704 | (ctx->total[1] << 3);
705 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
708 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100711 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100713
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200714 /*
715 * Output final state
716 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
718 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
719 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
720 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
721 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
722 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
723 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200725#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100726 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200727#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 if (!truncated) {
729 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
730 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100731
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100732 ret = 0;
733
734exit:
735 mbedtls_sha256_free(ctx);
736 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000737}
738
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200740
Paul Bakker5121ce52009-01-03 21:22:43 +0000741/*
742 * output = SHA-256( input buffer )
743 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100744int mbedtls_sha256(const unsigned char *input,
745 size_t ilen,
746 unsigned char *output,
747 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000748{
Janos Follath24eed8d2019-11-22 13:21:35 +0000749 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200750 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
Valerio Settia3f99592022-12-14 10:56:54 +0100752#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100754 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 }
Valerio Settia3f99592022-12-14 10:56:54 +0100756#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100758 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 }
Valerio Settia3f99592022-12-14 10:56:54 +0100760#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100762 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200764#endif
765
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100769 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100773 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100777 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100779
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100780exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100782
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000784}
785
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000787/*
788 * FIPS-180-2 test vectors
789 */
Valerio Settia3f99592022-12-14 10:56:54 +0100790static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000791{
792 { "abc" },
793 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
794 { "" }
795};
796
Valerio Settia3f99592022-12-14 10:56:54 +0100797static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000798{
799 3, 56, 1000
800};
801
Valerio Settia3f99592022-12-14 10:56:54 +0100802typedef const unsigned char (sha_test_sum_t)[32];
803
804/*
805 * SHA-224 test vectors
806 */
807#if defined(MBEDTLS_SHA224_C)
808static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000809{
Paul Bakker5121ce52009-01-03 21:22:43 +0000810 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
811 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
812 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
813 0xE3, 0x6C, 0x9D, 0xA7 },
814 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
815 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
816 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
817 0x52, 0x52, 0x25, 0x25 },
818 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
819 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
820 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100821 0x4E, 0xE7, 0xAD, 0x67 }
822};
823#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000824
Valerio Settia3f99592022-12-14 10:56:54 +0100825/*
826 * SHA-256 test vectors
827 */
828#if defined(MBEDTLS_SHA256_C)
829static sha_test_sum_t sha256_test_sum[] =
830{
Paul Bakker5121ce52009-01-03 21:22:43 +0000831 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
832 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
833 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
834 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
835 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
836 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
837 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
838 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
839 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
840 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
841 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
842 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
843};
Valerio Settia3f99592022-12-14 10:56:54 +0100844#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000845
846/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000847 * Checkup routine
848 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100849static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000850{
Valerio Settia3f99592022-12-14 10:56:54 +0100851 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500852 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200853 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000855
Valerio Settia3f99592022-12-14 10:56:54 +0100856#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100858#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100860#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100862#endif
863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 buf = mbedtls_calloc(1024, sizeof(unsigned char));
865 if (NULL == buf) {
866 if (verbose != 0) {
867 mbedtls_printf("Buffer allocation failed\n");
868 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500871 }
872
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 for (i = 0; i < 3; i++) {
876 if (verbose != 0) {
877 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
878 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000879
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100881 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if (i == 2) {
885 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 for (int j = 0; j < 1000; j++) {
888 ret = mbedtls_sha256_update(&ctx, buf, buflen);
889 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100890 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100892 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 } else {
895 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
896 sha_test_buflen[i]);
897 if (ret != 0) {
898 goto fail;
899 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100900 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100903 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100905
Paul Bakker5121ce52009-01-03 21:22:43 +0000906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100908 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100909 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100910 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 if (verbose != 0) {
913 mbedtls_printf("passed\n");
914 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000915 }
916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 if (verbose != 0) {
918 mbedtls_printf("\n");
919 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100921 goto exit;
922
923fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 if (verbose != 0) {
925 mbedtls_printf("failed\n");
926 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100927
Paul Bakker5b4af392014-06-26 12:09:34 +0200928exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 mbedtls_sha256_free(&ctx);
930 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000933}
934
Valerio Settia3f99592022-12-14 10:56:54 +0100935#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100936int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100937{
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100939}
940#endif /* MBEDTLS_SHA256_C */
941
942#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100943int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100944{
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100946}
947#endif /* MBEDTLS_SHA224_C */
948
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000950
Valerio Settia3f99592022-12-14 10:56:54 +0100951#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */