blob: c167dbe1a807c0c4ce6137ee934412fba221264a [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) && \
26 defined(__clang__) && __clang_major__ < 18 && __clang_major__ > 3
27/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
28 *
29 * The intrinsic declaration are guarded with ACLE predefined macros in clang,
30 * and those macros are only enabled with command line. Define the macros can
31 * enable those declaration and avoid compile error on it.
32 */
33#define __ARM_FEATURE_CRYPTO 1
34#pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
35#define MBEDTLS_POP_TARGET_PRAGMA
36#endif /* __aarch64__ && __clang__ &&
37 !__ARM_FEATURE_CRYPTO && __clang_major__ < 18 && __clang_major__ > 3 */
38
Gilles Peskinedb09ef62020-06-03 01:43:33 +020039#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Jerry Yua135dee2023-02-16 16:56:22 +080041#if defined(MBEDTLS_POP_TARGET_PRAGMA) && \
42 !(defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
43 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY))
44#if defined(__clang__)
45#pragma clang attribute pop
46#endif
47#undef MBEDTLS_POP_TARGET_PRAGMA
48#endif
49
Valerio Settia3f99592022-12-14 10:56:54 +010050#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000051
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000052#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050053#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000054#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000055
Rich Evans00ab4702015-02-06 13:43:58 +000056#include <string.h>
57
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000058#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010059
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000060#if defined(__aarch64__)
61# 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 Yu35f2b262023-02-15 11:35:55 +080063/* *INDENT-OFF* */
64# if !defined(__ARM_FEATURE_CRYPTO)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080065# if defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080066# if __clang_major__ < 4
67# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080068# endif
69# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
70# define MBEDTLS_POP_TARGET_PRAGMA
71# elif defined(__GNUC__)
Jerry Yu8ae6a012023-02-16 15:16:20 +080072 /* FIXME: GCC-5 annouce crypto extension, but some intrinsic are missed.
73 * Known miss intrinsic can be workaround.
74 */
75# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080076# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
77# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080078# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080079# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080080# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080081# endif
82# else
83# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
84# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080085# endif
86/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000087# include <arm_neon.h>
88# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000089# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
90# if defined(__unix__)
91# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010092/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000093# include <sys/auxv.h>
94# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010095/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000096# include <signal.h>
97# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000098# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000099#elif defined(_M_ARM64)
100# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000102# include <arm64_neon.h>
103# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000104#else
105# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
106# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
107#endif
108
109#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
110/*
111 * Capability detection code comes early, so we can disable
112 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
113 */
114#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100115static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000116{
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000118}
119#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100120static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000121{
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000123}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000124#elif defined(_M_ARM64)
125#define WIN32_LEAN_AND_MEAN
126#include <Windows.h>
127#include <processthreadsapi.h>
128
Gilles Peskine449bd832023-01-11 14:50:10 +0100129static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000130{
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
132 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000133}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000134#elif defined(__unix__) && defined(SIG_SETMASK)
135/* Detection with SIGILL, setjmp() and longjmp() */
136#include <signal.h>
137#include <setjmp.h>
138
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000139static jmp_buf return_from_sigill;
140
141/*
142 * A64 SHA256 support detection via SIGILL
143 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100144static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000145{
146 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000148}
149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000151{
152 struct sigaction old_action, new_action;
153
154 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 if (sigprocmask(0, NULL, &old_mask)) {
156 return 0;
157 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000158
Gilles Peskine449bd832023-01-11 14:50:10 +0100159 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000160 new_action.sa_flags = 0;
161 new_action.sa_handler = sigill_handler;
162
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000164
165 static int ret = 0;
166
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000168 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000170 ret = 1;
171 }
172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 sigaction(SIGILL, &old_action, NULL);
174 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000177}
178#else
179#warning "No mechanism to detect A64_CRYPTO found, using C code only"
180#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
181#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
182
183#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
184
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200185#if !defined(MBEDTLS_SHA256_ALT)
186
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000187#define SHA256_BLOCK_SIZE 64
188
Gilles Peskine449bd832023-01-11 14:50:10 +0100189void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200190{
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200192}
193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200195{
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200197 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200201}
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
204 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200205{
206 *dst = *src;
207}
208
Paul Bakker5121ce52009-01-03 21:22:43 +0000209/*
210 * SHA-256 context setup
211 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100212int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000213{
Valerio Settia3f99592022-12-14 10:56:54 +0100214#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100216 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 }
Valerio Settia3f99592022-12-14 10:56:54 +0100218#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100220 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 }
Valerio Settia3f99592022-12-14 10:56:54 +0100222#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100224 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200226#endif
227
Paul Bakker5121ce52009-01-03 21:22:43 +0000228 ctx->total[0] = 0;
229 ctx->total[1] = 0;
230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100232#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 ctx->state[0] = 0x6A09E667;
234 ctx->state[1] = 0xBB67AE85;
235 ctx->state[2] = 0x3C6EF372;
236 ctx->state[3] = 0xA54FF53A;
237 ctx->state[4] = 0x510E527F;
238 ctx->state[5] = 0x9B05688C;
239 ctx->state[6] = 0x1F83D9AB;
240 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100241#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200243#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000244 ctx->state[0] = 0xC1059ED8;
245 ctx->state[1] = 0x367CD507;
246 ctx->state[2] = 0x3070DD17;
247 ctx->state[3] = 0xF70E5939;
248 ctx->state[4] = 0xFFC00B31;
249 ctx->state[5] = 0x68581511;
250 ctx->state[6] = 0x64F98FA7;
251 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200252#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 }
254
Valerio Settia3f99592022-12-14 10:56:54 +0100255#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000256 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100257#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000260}
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200263static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000264{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200265 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
266 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
267 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
268 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
269 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
270 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
271 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
272 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
273 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
274 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
275 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
276 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
277 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
278 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
279 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
280 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
281};
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000283#endif
284
285#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
286 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
287
288#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
289# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
290# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
291#endif
292
293static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000295{
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
297 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000298
299 size_t processed = 0;
300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000302 len >= SHA256_BLOCK_SIZE;
303 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 msg += SHA256_BLOCK_SIZE,
305 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000306 uint32x4_t tmp, abcd_prev;
307
308 uint32x4_t abcd_orig = abcd;
309 uint32x4_t efgh_orig = efgh;
310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
312 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
313 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
314 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000315
316#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
317 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
319 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
320 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
321 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000322#endif
323
324 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000326 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
328 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000329
330 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000332 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
334 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000335
336 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000338 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
340 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000341
342 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000344 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
346 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000349 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
351 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000352 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
354 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000355
356 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
358 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
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 + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
365 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
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 + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
372 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000373 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
375 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000376 }
377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 abcd = vaddq_u32(abcd, abcd_orig);
379 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000380 }
381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 vst1q_u32(&ctx->state[0], abcd);
383 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000384
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000386}
387
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100388#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
389/*
390 * This function is for internal use only if we are building both C and A64
391 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
392 */
393static
394#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100395int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
396 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000397{
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
399 SHA256_BLOCK_SIZE) ==
400 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000401}
402
Jerry Yu92fc5382023-02-16 11:17:11 +0800403#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800404#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800405#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800406#elif defined(__GNUC__)
407#pragma GCC pop_options
408#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800409#undef MBEDTLS_POP_TARGET_PRAGMA
410#endif
411
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000412#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
413
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000414#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
415#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
416#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
417#endif
418
419
420#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
421 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
424#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
427#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
430#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
433#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200435#define R(t) \
436 ( \
437 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
438 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100439 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200442 do \
443 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
445 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200446 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100449#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
450/*
451 * This function is for internal use only if we are building both C and A64
452 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
453 */
454static
455#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100456int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
457 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200458{
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200460 uint32_t temp1, temp2, W[64];
461 uint32_t A[8];
462 } local;
463
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200464 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200467 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200469
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200470#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 for (i = 0; i < 64; i++) {
472 if (i < 16) {
473 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
474 } else {
475 R(i);
476 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
479 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200480
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200481 local.temp1 = local.A[7]; local.A[7] = local.A[6];
482 local.A[6] = local.A[5]; local.A[5] = local.A[4];
483 local.A[4] = local.A[3]; local.A[3] = local.A[2];
484 local.A[2] = local.A[1]; local.A[1] = local.A[0];
485 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200486 }
487#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 for (i = 0; i < 16; i++) {
489 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200490 }
491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 for (i = 0; i < 16; i += 8) {
493 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
494 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
495 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
496 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
497 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
498 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
499 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
500 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
501 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
502 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
503 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
504 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
505 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
506 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
507 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
508 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
509 }
510
511 for (i = 16; i < 64; i += 8) {
512 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
513 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
514 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
515 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
516 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
517 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
518 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
519 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
520 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
521 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
522 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
523 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
524 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
525 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
526 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
527 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200528 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200529#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200532 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100534
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200535 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000539}
Jaeden Amero041039f2018-02-19 15:28:08 +0000540
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000541#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
542
543
544#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
545
546static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000548{
549 size_t processed = 0;
550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 while (len >= SHA256_BLOCK_SIZE) {
552 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
553 return 0;
554 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000555
556 data += SHA256_BLOCK_SIZE;
557 len -= SHA256_BLOCK_SIZE;
558
559 processed += SHA256_BLOCK_SIZE;
560 }
561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000563}
564
565#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
566
567
568#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000571{
572 static int done = 0;
573 static int supported = 0;
574
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000576 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000577 done = 1;
578 }
579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000581}
582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
584 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000585{
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 if (mbedtls_a64_crypto_sha256_has_support()) {
587 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
588 } else {
589 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
590 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000591}
592
Gilles Peskine449bd832023-01-11 14:50:10 +0100593int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
594 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000595{
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 if (mbedtls_a64_crypto_sha256_has_support()) {
597 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
598 } else {
599 return mbedtls_internal_sha256_process_c(ctx, data);
600 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000601}
602
603#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
604
Paul Bakker5121ce52009-01-03 21:22:43 +0000605
606/*
607 * SHA-256 process buffer
608 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100609int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
610 const unsigned char *input,
611 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000612{
Janos Follath24eed8d2019-11-22 13:21:35 +0000613 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000614 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000615 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 if (ilen == 0) {
618 return 0;
619 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
621 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000622 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
Paul Bakker5c2364c2012-10-01 14:41:15 +0000624 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 ctx->total[0] &= 0xFFFFFFFF;
626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 if (left && ilen >= fill) {
632 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
635 return ret;
636 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100637
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 input += fill;
639 ilen -= fill;
640 left = 0;
641 }
642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000644 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 mbedtls_internal_sha256_process_many(ctx, input, ilen);
646 if (processed < SHA256_BLOCK_SIZE) {
647 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
648 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100649
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000650 input += processed;
651 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 }
653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 if (ilen > 0) {
655 memcpy((void *) (ctx->buffer + left), input, ilen);
656 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000659}
660
Paul Bakker5121ce52009-01-03 21:22:43 +0000661/*
662 * SHA-256 final digest
663 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100664int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
665 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000666{
Janos Follath24eed8d2019-11-22 13:21:35 +0000667 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200668 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000669 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200671 /*
672 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
673 */
674 used = ctx->total[0] & 0x3F;
675
676 ctx->buffer[used++] = 0x80;
677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200679 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 memset(ctx->buffer + used, 0, 56 - used);
681 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200682 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
686 return ret;
687 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200690 }
691
692 /*
693 * Add message length
694 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 high = (ctx->total[0] >> 29)
696 | (ctx->total[1] << 3);
697 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
700 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000701
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
703 return ret;
704 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100705
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200706 /*
707 * Output final state
708 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
710 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
711 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
712 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
713 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
714 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
715 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000716
David Horstmann687262c2022-10-06 17:54:57 +0100717 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200718#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100719 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200720#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 if (!truncated) {
722 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
723 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000726}
727
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200729
Paul Bakker5121ce52009-01-03 21:22:43 +0000730/*
731 * output = SHA-256( input buffer )
732 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100733int mbedtls_sha256(const unsigned char *input,
734 size_t ilen,
735 unsigned char *output,
736 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000737{
Janos Follath24eed8d2019-11-22 13:21:35 +0000738 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000740
Valerio Settia3f99592022-12-14 10:56:54 +0100741#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100743 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 }
Valerio Settia3f99592022-12-14 10:56:54 +0100745#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100747 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 }
Valerio Settia3f99592022-12-14 10:56:54 +0100749#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100751 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200753#endif
754
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100758 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100760
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100762 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100766 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100768
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100769exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000773}
774
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000776/*
777 * FIPS-180-2 test vectors
778 */
Valerio Settia3f99592022-12-14 10:56:54 +0100779static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000780{
781 { "abc" },
782 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
783 { "" }
784};
785
Valerio Settia3f99592022-12-14 10:56:54 +0100786static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000787{
788 3, 56, 1000
789};
790
Valerio Settia3f99592022-12-14 10:56:54 +0100791typedef const unsigned char (sha_test_sum_t)[32];
792
793/*
794 * SHA-224 test vectors
795 */
796#if defined(MBEDTLS_SHA224_C)
797static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000798{
Paul Bakker5121ce52009-01-03 21:22:43 +0000799 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
800 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
801 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
802 0xE3, 0x6C, 0x9D, 0xA7 },
803 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
804 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
805 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
806 0x52, 0x52, 0x25, 0x25 },
807 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
808 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
809 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100810 0x4E, 0xE7, 0xAD, 0x67 }
811};
812#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
Valerio Settia3f99592022-12-14 10:56:54 +0100814/*
815 * SHA-256 test vectors
816 */
817#if defined(MBEDTLS_SHA256_C)
818static sha_test_sum_t sha256_test_sum[] =
819{
Paul Bakker5121ce52009-01-03 21:22:43 +0000820 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
821 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
822 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
823 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
824 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
825 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
826 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
827 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
828 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
829 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
830 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
831 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
832};
Valerio Settia3f99592022-12-14 10:56:54 +0100833#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000834
835/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000836 * Checkup routine
837 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100838static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000839{
Valerio Settia3f99592022-12-14 10:56:54 +0100840 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500841 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200842 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000844
Valerio Settia3f99592022-12-14 10:56:54 +0100845#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100847#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100849#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100851#endif
852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 buf = mbedtls_calloc(1024, sizeof(unsigned char));
854 if (NULL == buf) {
855 if (verbose != 0) {
856 mbedtls_printf("Buffer allocation failed\n");
857 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500860 }
861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 for (i = 0; i < 3; i++) {
865 if (verbose != 0) {
866 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
867 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100870 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000872
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 if (i == 2) {
874 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 for (int j = 0; j < 1000; j++) {
877 ret = mbedtls_sha256_update(&ctx, buf, buflen);
878 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100879 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100881 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100882
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 } else {
884 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
885 sha_test_buflen[i]);
886 if (ret != 0) {
887 goto fail;
888 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100889 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100892 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100894
Paul Bakker5121ce52009-01-03 21:22:43 +0000895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100897 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100898 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100899 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 if (verbose != 0) {
902 mbedtls_printf("passed\n");
903 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000904 }
905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 if (verbose != 0) {
907 mbedtls_printf("\n");
908 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000909
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100910 goto exit;
911
912fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 if (verbose != 0) {
914 mbedtls_printf("failed\n");
915 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100916
Paul Bakker5b4af392014-06-26 12:09:34 +0200917exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 mbedtls_sha256_free(&ctx);
919 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000922}
923
Valerio Settia3f99592022-12-14 10:56:54 +0100924#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100925int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100926{
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100928}
929#endif /* MBEDTLS_SHA256_C */
930
931#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100932int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100933{
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100935}
936#endif /* MBEDTLS_SHA224_C */
937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
Valerio Settia3f99592022-12-14 10:56:54 +0100940#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */