blob: b603b86c98819c5ef72588a1384a5a117e8d9f27 [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 *
Jerry Yufc2e1282023-02-27 11:16:56 +080034 * `arm_neon.h` could be included by any header file, so we put these defines
35 * 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
Dave Rodgman7ed619d2023-10-05 09:39:56 +010047/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
48#define _GNU_SOURCE
49
Gilles Peskinedb09ef62020-06-03 01:43:33 +020050#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000051
Valerio Settia3f99592022-12-14 10:56:54 +010052#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000053
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050055#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000056#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000057
Rich Evans00ab4702015-02-06 13:43:58 +000058#include <string.h>
59
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000060#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010061
Dave Rodgmancc5bf492023-10-03 18:02:56 +010062#if defined(MBEDTLS_ARCH_IS_ARMV8)
Jerry Yu08933d32023-04-27 18:28:00 +080063
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000064# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010065 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Jerry Yu08933d32023-04-27 18:28:00 +080066
Jerry Yu35f2b262023-02-15 11:35:55 +080067/* *INDENT-OFF* */
Jerry Yu6b00f5a2023-05-04 16:30:21 +080068
69# ifdef __ARM_NEON
70# include <arm_neon.h>
71# else
72# error "Target does not support NEON instructions"
73# endif
74
Dave Rodgman793e2642023-10-04 17:36:20 +010075# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
Jerry Yub1d06bb2023-05-05 14:05:07 +080076# if defined(__ARMCOMPILER_VERSION)
77# if __ARMCOMPILER_VERSION <= 6090000
78# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
79# endif
80# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
81# define MBEDTLS_POP_TARGET_PRAGMA
82# elif defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080083# if __clang_major__ < 4
84# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080085# endif
Jerry Yub1d06bb2023-05-05 14:05:07 +080086# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080087# define MBEDTLS_POP_TARGET_PRAGMA
88# elif defined(__GNUC__)
Tom Cosgrovec15a2b92023-03-08 12:55:48 +000089 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
90 * intrinsics are missing. Missing intrinsics could be worked around.
Jerry Yu8ae6a012023-02-16 15:16:20 +080091 */
92# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080093# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
94# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080095# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080096# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080097# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080098# endif
99# else
100# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
101# endif
Jerry Yu35f2b262023-02-15 11:35:55 +0800102# endif
103/* *INDENT-ON* */
Jerry Yu08933d32023-04-27 18:28:00 +0800104
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000105# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000106# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
107# if defined(__unix__)
108# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100109/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000110# include <sys/auxv.h>
111# endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100112/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000113# include <signal.h>
114# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000115# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000116#elif defined(_M_ARM64)
117# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000119# include <arm64_neon.h>
120# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000121#else
122# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
123# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
124#endif
125
126#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
127/*
128 * Capability detection code comes early, so we can disable
129 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
130 */
131#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100132static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000133{
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000135}
136#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100137static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000138{
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000140}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000141#elif defined(_M_ARM64)
142#define WIN32_LEAN_AND_MEAN
143#include <Windows.h>
144#include <processthreadsapi.h>
145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000147{
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
149 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000150}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000151#elif defined(__unix__) && defined(SIG_SETMASK)
152/* Detection with SIGILL, setjmp() and longjmp() */
153#include <signal.h>
154#include <setjmp.h>
155
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000156static jmp_buf return_from_sigill;
157
158/*
159 * A64 SHA256 support detection via SIGILL
160 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100161static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000162{
163 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000165}
166
Gilles Peskine449bd832023-01-11 14:50:10 +0100167static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000168{
169 struct sigaction old_action, new_action;
170
171 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 if (sigprocmask(0, NULL, &old_mask)) {
173 return 0;
174 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000177 new_action.sa_flags = 0;
178 new_action.sa_handler = sigill_handler;
179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000181
182 static int ret = 0;
183
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000185 /* If this traps, we will return a second time from setjmp() with 1 */
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100186#if defined(MBEDTLS_ARCH_IS_ARM64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Dave Rodgman7ed619d2023-10-05 09:39:56 +0100188#else
189 asm ("sha256h.32 q0, q0, q0" : : : "q0");
190#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000191 ret = 1;
192 }
193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 sigaction(SIGILL, &old_action, NULL);
195 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000198}
199#else
200#warning "No mechanism to detect A64_CRYPTO found, using C code only"
201#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
202#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
203
204#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
205
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200206#if !defined(MBEDTLS_SHA256_ALT)
207
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000208#define SHA256_BLOCK_SIZE 64
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200211{
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200213}
214
Gilles Peskine449bd832023-01-11 14:50:10 +0100215void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200216{
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200218 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200222}
223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
225 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200226{
227 *dst = *src;
228}
229
Paul Bakker5121ce52009-01-03 21:22:43 +0000230/*
231 * SHA-256 context setup
232 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100233int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000234{
Valerio Settia3f99592022-12-14 10:56:54 +0100235#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100237 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 }
Valerio Settia3f99592022-12-14 10:56:54 +0100239#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100241 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 }
Valerio Settia3f99592022-12-14 10:56:54 +0100243#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100245 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200247#endif
248
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 ctx->total[0] = 0;
250 ctx->total[1] = 0;
251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100253#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000254 ctx->state[0] = 0x6A09E667;
255 ctx->state[1] = 0xBB67AE85;
256 ctx->state[2] = 0x3C6EF372;
257 ctx->state[3] = 0xA54FF53A;
258 ctx->state[4] = 0x510E527F;
259 ctx->state[5] = 0x9B05688C;
260 ctx->state[6] = 0x1F83D9AB;
261 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100262#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200264#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000265 ctx->state[0] = 0xC1059ED8;
266 ctx->state[1] = 0x367CD507;
267 ctx->state[2] = 0x3070DD17;
268 ctx->state[3] = 0xF70E5939;
269 ctx->state[4] = 0xFFC00B31;
270 ctx->state[5] = 0x68581511;
271 ctx->state[6] = 0x64F98FA7;
272 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200273#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000274 }
275
Valerio Settia3f99592022-12-14 10:56:54 +0100276#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100278#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000281}
282
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200284static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000285{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200286 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
287 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
288 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
289 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
290 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
291 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
292 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
293 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
294 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
295 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
296 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
297 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
298 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
299 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
300 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
301 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
302};
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000304#endif
305
306#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
307 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
308
309#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
310# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
311# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
312#endif
313
314static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000316{
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
318 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000319
320 size_t processed = 0;
321
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000323 len >= SHA256_BLOCK_SIZE;
324 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 msg += SHA256_BLOCK_SIZE,
326 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000327 uint32x4_t tmp, abcd_prev;
328
329 uint32x4_t abcd_orig = abcd;
330 uint32x4_t efgh_orig = efgh;
331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
333 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
334 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
335 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000336
337#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
338 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
340 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
341 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
342 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000343#endif
344
345 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000347 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
349 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000350
351 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000353 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
355 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000356
357 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
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 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000365 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
367 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000370 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
372 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
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 + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
379 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
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 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
386 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000387 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
389 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000390
391 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
393 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000394 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
396 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000397 }
398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 abcd = vaddq_u32(abcd, abcd_orig);
400 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000401 }
402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 vst1q_u32(&ctx->state[0], abcd);
404 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000407}
408
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100409#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
410/*
411 * This function is for internal use only if we are building both C and A64
412 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
413 */
414static
415#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100416int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
417 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000418{
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
420 SHA256_BLOCK_SIZE) ==
421 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000422}
423
Tom Cosgroveef2aa0e2023-06-09 11:29:50 +0100424#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
425
Jerry Yu92fc5382023-02-16 11:17:11 +0800426#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800427#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800428#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800429#elif defined(__GNUC__)
430#pragma GCC pop_options
431#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800432#undef MBEDTLS_POP_TARGET_PRAGMA
433#endif
434
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000435#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
436#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
437#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
438#endif
439
440
441#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
442 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
445#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
Gilles Peskine449bd832023-01-11 14:50:10 +0100447#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
448#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
Gilles Peskine449bd832023-01-11 14:50:10 +0100450#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
451#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
454#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200456#define R(t) \
457 ( \
458 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
459 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100460 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200463 do \
464 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
466 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200467 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100470#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
471/*
472 * This function is for internal use only if we are building both C and A64
473 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
474 */
475static
476#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100477int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
478 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200479{
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200481 uint32_t temp1, temp2, W[64];
482 uint32_t A[8];
483 } local;
484
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200485 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200488 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200490
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200491#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 for (i = 0; i < 64; i++) {
493 if (i < 16) {
494 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
495 } else {
496 R(i);
497 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
500 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200501
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200502 local.temp1 = local.A[7]; local.A[7] = local.A[6];
503 local.A[6] = local.A[5]; local.A[5] = local.A[4];
504 local.A[4] = local.A[3]; local.A[3] = local.A[2];
505 local.A[2] = local.A[1]; local.A[1] = local.A[0];
506 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200507 }
508#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 for (i = 0; i < 16; i++) {
510 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200511 }
512
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 for (i = 0; i < 16; i += 8) {
514 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+0], K[i+0]);
516 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
517 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
518 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
519 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
520 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
521 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
522 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
523 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
524 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
525 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
526 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
527 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
528 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
529 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
530 }
531
532 for (i = 16; i < 64; i += 8) {
533 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
534 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
535 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
536 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
537 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
538 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
539 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
540 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
541 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
542 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
543 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
544 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
545 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
546 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
547 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
548 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200549 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200550#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200553 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100555
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200556 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000560}
Jaeden Amero041039f2018-02-19 15:28:08 +0000561
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000562#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
563
564
565#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
566
567static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000569{
570 size_t processed = 0;
571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 while (len >= SHA256_BLOCK_SIZE) {
573 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
574 return 0;
575 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000576
577 data += SHA256_BLOCK_SIZE;
578 len -= SHA256_BLOCK_SIZE;
579
580 processed += SHA256_BLOCK_SIZE;
581 }
582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000584}
585
586#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
587
588
589#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
590
Gilles Peskine449bd832023-01-11 14:50:10 +0100591static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000592{
593 static int done = 0;
594 static int supported = 0;
595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000597 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000598 done = 1;
599 }
600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000602}
603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
605 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000606{
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 if (mbedtls_a64_crypto_sha256_has_support()) {
608 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
609 } else {
610 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
611 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000612}
613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
615 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000616{
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 if (mbedtls_a64_crypto_sha256_has_support()) {
618 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
619 } else {
620 return mbedtls_internal_sha256_process_c(ctx, data);
621 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000622}
623
624#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
625
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
627/*
628 * SHA-256 process buffer
629 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100630int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
631 const unsigned char *input,
632 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000633{
Janos Follath24eed8d2019-11-22 13:21:35 +0000634 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000635 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000636 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (ilen == 0) {
639 return 0;
640 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
642 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000643 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
Paul Bakker5c2364c2012-10-01 14:41:15 +0000645 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 ctx->total[0] &= 0xFFFFFFFF;
647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000649 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if (left && ilen >= fill) {
653 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
656 return ret;
657 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100658
Paul Bakker5121ce52009-01-03 21:22:43 +0000659 input += fill;
660 ilen -= fill;
661 left = 0;
662 }
663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000665 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 mbedtls_internal_sha256_process_many(ctx, input, ilen);
667 if (processed < SHA256_BLOCK_SIZE) {
668 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
669 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100670
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000671 input += processed;
672 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 }
674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 if (ilen > 0) {
676 memcpy((void *) (ctx->buffer + left), input, ilen);
677 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000680}
681
Paul Bakker5121ce52009-01-03 21:22:43 +0000682/*
683 * SHA-256 final digest
684 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100685int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
686 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000687{
Janos Follath24eed8d2019-11-22 13:21:35 +0000688 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200689 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000690 uint32_t high, low;
Dave Rodgman90330a42023-09-28 17:24:06 +0100691 int truncated = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200693 /*
694 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
695 */
696 used = ctx->total[0] & 0x3F;
697
698 ctx->buffer[used++] = 0x80;
699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200701 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 memset(ctx->buffer + used, 0, 56 - used);
703 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200704 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100708 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200712 }
713
714 /*
715 * Add message length
716 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 high = (ctx->total[0] >> 29)
718 | (ctx->total[1] << 3);
719 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
722 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100725 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100727
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200728 /*
729 * Output final state
730 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
732 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
733 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
734 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
735 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
736 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
737 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000738
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200739#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100740 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200741#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 if (!truncated) {
743 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
744 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100745
Dave Rodgmanaafd1e02023-09-11 12:59:36 +0100746 ret = 0;
747
748exit:
749 mbedtls_sha256_free(ctx);
750 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000751}
752
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200754
Paul Bakker5121ce52009-01-03 21:22:43 +0000755/*
756 * output = SHA-256( input buffer )
757 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758int mbedtls_sha256(const unsigned char *input,
759 size_t ilen,
760 unsigned char *output,
761 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000762{
Janos Follath24eed8d2019-11-22 13:21:35 +0000763 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200764 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000765
Valerio Settia3f99592022-12-14 10:56:54 +0100766#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100768 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 }
Valerio Settia3f99592022-12-14 10:56:54 +0100770#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100772 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 }
Valerio Settia3f99592022-12-14 10:56:54 +0100774#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100776 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200778#endif
779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100783 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100785
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100787 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100791 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100793
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100794exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000798}
799
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000801/*
802 * FIPS-180-2 test vectors
803 */
Valerio Settia3f99592022-12-14 10:56:54 +0100804static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000805{
806 { "abc" },
807 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
808 { "" }
809};
810
Valerio Settia3f99592022-12-14 10:56:54 +0100811static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000812{
813 3, 56, 1000
814};
815
Valerio Settia3f99592022-12-14 10:56:54 +0100816typedef const unsigned char (sha_test_sum_t)[32];
817
818/*
819 * SHA-224 test vectors
820 */
821#if defined(MBEDTLS_SHA224_C)
822static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000823{
Paul Bakker5121ce52009-01-03 21:22:43 +0000824 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
825 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
826 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
827 0xE3, 0x6C, 0x9D, 0xA7 },
828 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
829 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
830 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
831 0x52, 0x52, 0x25, 0x25 },
832 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
833 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
834 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100835 0x4E, 0xE7, 0xAD, 0x67 }
836};
837#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
Valerio Settia3f99592022-12-14 10:56:54 +0100839/*
840 * SHA-256 test vectors
841 */
842#if defined(MBEDTLS_SHA256_C)
843static sha_test_sum_t sha256_test_sum[] =
844{
Paul Bakker5121ce52009-01-03 21:22:43 +0000845 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
846 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
847 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
848 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
849 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
850 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
851 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
852 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
853 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
854 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
855 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
856 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
857};
Valerio Settia3f99592022-12-14 10:56:54 +0100858#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000859
860/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000861 * Checkup routine
862 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100863static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000864{
Valerio Settia3f99592022-12-14 10:56:54 +0100865 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500866 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200867 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
Valerio Settia3f99592022-12-14 10:56:54 +0100870#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100872#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100874#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100876#endif
877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 buf = mbedtls_calloc(1024, sizeof(unsigned char));
879 if (NULL == buf) {
880 if (verbose != 0) {
881 mbedtls_printf("Buffer allocation failed\n");
882 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500885 }
886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 for (i = 0; i < 3; i++) {
890 if (verbose != 0) {
891 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
892 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100895 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 if (i == 2) {
899 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 for (int j = 0; j < 1000; j++) {
902 ret = mbedtls_sha256_update(&ctx, buf, buflen);
903 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100904 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100906 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 } else {
909 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
910 sha_test_buflen[i]);
911 if (ret != 0) {
912 goto fail;
913 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100914 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000915
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100917 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100919
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100922 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100923 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100924 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000925
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 if (verbose != 0) {
927 mbedtls_printf("passed\n");
928 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000929 }
930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 if (verbose != 0) {
932 mbedtls_printf("\n");
933 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100935 goto exit;
936
937fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 if (verbose != 0) {
939 mbedtls_printf("failed\n");
940 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100941
Paul Bakker5b4af392014-06-26 12:09:34 +0200942exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 mbedtls_sha256_free(&ctx);
944 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000947}
948
Valerio Settia3f99592022-12-14 10:56:54 +0100949#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100950int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100951{
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100953}
954#endif /* MBEDTLS_SHA256_C */
955
956#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100957int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100958{
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100960}
961#endif /* MBEDTLS_SHA224_C */
962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000964
Valerio Settia3f99592022-12-14 10:56:54 +0100965#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */