blob: d18f22848784511c7db42eb2428712681808b6d9 [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.
Jerry Yu4d786a72023-02-22 11:01:07 +080032 *
33 * `arm_neon.h` might be included in any head files. On the top of this file, we
34 * can guarantee this workaround always work.
Jerry Yua135dee2023-02-16 16:56:22 +080035 */
36#define __ARM_FEATURE_CRYPTO 1
Jerry Yu4d786a72023-02-22 11:01:07 +080037#define NEED_TARGET_OPTIONS
Jerry Yua135dee2023-02-16 16:56:22 +080038#endif /* __aarch64__ && __clang__ &&
Jerry Yuba4ec242023-02-21 15:59:13 +080039 !__ARM_FEATURE_CRYPTO && __clang_major__ < 18 && __clang_major__ > 3 */
Jerry Yua135dee2023-02-16 16:56:22 +080040
Gilles Peskinedb09ef62020-06-03 01:43:33 +020041#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000042
Valerio Settia3f99592022-12-14 10:56:54 +010043#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000044
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050046#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000047#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000048
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <string.h>
50
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000051#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000053#if defined(__aarch64__)
54# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010055 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080056/* *INDENT-OFF* */
Jerry Yu4d786a72023-02-22 11:01:07 +080057# if !defined(__ARM_FEATURE_CRYPTO) || defined(NEED_TARGET_OPTIONS)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080058# if defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080059# if __clang_major__ < 4
60# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080061# endif
62# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
63# define MBEDTLS_POP_TARGET_PRAGMA
64# elif defined(__GNUC__)
Jerry Yu8ae6a012023-02-16 15:16:20 +080065 /* FIXME: GCC-5 annouce crypto extension, but some intrinsic are missed.
66 * Known miss intrinsic can be workaround.
67 */
68# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080069# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
70# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080071# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080072# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080073# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080074# endif
75# else
76# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
77# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080078# endif
79/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000080# include <arm_neon.h>
81# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000082# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
83# if defined(__unix__)
84# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010085/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000086# include <sys/auxv.h>
87# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010088/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000089# include <signal.h>
90# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000091# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000092#elif defined(_M_ARM64)
93# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010094 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000095# include <arm64_neon.h>
96# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000097#else
98# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
99# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
100#endif
101
102#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
103/*
104 * Capability detection code comes early, so we can disable
105 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
106 */
107#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100108static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000109{
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000111}
112#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100113static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000114{
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000116}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000117#elif defined(_M_ARM64)
118#define WIN32_LEAN_AND_MEAN
119#include <Windows.h>
120#include <processthreadsapi.h>
121
Gilles Peskine449bd832023-01-11 14:50:10 +0100122static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000123{
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
125 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000126}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000127#elif defined(__unix__) && defined(SIG_SETMASK)
128/* Detection with SIGILL, setjmp() and longjmp() */
129#include <signal.h>
130#include <setjmp.h>
131
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000132static jmp_buf return_from_sigill;
133
134/*
135 * A64 SHA256 support detection via SIGILL
136 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100137static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000138{
139 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000141}
142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000144{
145 struct sigaction old_action, new_action;
146
147 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 if (sigprocmask(0, NULL, &old_mask)) {
149 return 0;
150 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000151
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000153 new_action.sa_flags = 0;
154 new_action.sa_handler = sigill_handler;
155
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000157
158 static int ret = 0;
159
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000161 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000163 ret = 1;
164 }
165
Gilles Peskine449bd832023-01-11 14:50:10 +0100166 sigaction(SIGILL, &old_action, NULL);
167 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000170}
171#else
172#warning "No mechanism to detect A64_CRYPTO found, using C code only"
173#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
174#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
175
176#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
177
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200178#if !defined(MBEDTLS_SHA256_ALT)
179
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000180#define SHA256_BLOCK_SIZE 64
181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200183{
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200185}
186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200188{
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200190 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200194}
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
197 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200198{
199 *dst = *src;
200}
201
Paul Bakker5121ce52009-01-03 21:22:43 +0000202/*
203 * SHA-256 context setup
204 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100205int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000206{
Valerio Settia3f99592022-12-14 10:56:54 +0100207#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100209 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 }
Valerio Settia3f99592022-12-14 10:56:54 +0100211#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100213 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 }
Valerio Settia3f99592022-12-14 10:56:54 +0100215#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100216 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100217 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200219#endif
220
Paul Bakker5121ce52009-01-03 21:22:43 +0000221 ctx->total[0] = 0;
222 ctx->total[1] = 0;
223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100225#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000226 ctx->state[0] = 0x6A09E667;
227 ctx->state[1] = 0xBB67AE85;
228 ctx->state[2] = 0x3C6EF372;
229 ctx->state[3] = 0xA54FF53A;
230 ctx->state[4] = 0x510E527F;
231 ctx->state[5] = 0x9B05688C;
232 ctx->state[6] = 0x1F83D9AB;
233 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100234#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200236#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000237 ctx->state[0] = 0xC1059ED8;
238 ctx->state[1] = 0x367CD507;
239 ctx->state[2] = 0x3070DD17;
240 ctx->state[3] = 0xF70E5939;
241 ctx->state[4] = 0xFFC00B31;
242 ctx->state[5] = 0x68581511;
243 ctx->state[6] = 0x64F98FA7;
244 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200245#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000246 }
247
Valerio Settia3f99592022-12-14 10:56:54 +0100248#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100250#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000253}
254
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200255#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200256static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000257{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200258 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
259 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
260 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
261 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
262 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
263 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
264 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
265 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
266 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
267 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
268 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
269 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
270 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
271 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
272 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
273 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
274};
Paul Bakker5121ce52009-01-03 21:22:43 +0000275
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000276#endif
277
278#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
279 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
280
281#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
282# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
283# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
284#endif
285
286static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000288{
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
290 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000291
292 size_t processed = 0;
293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000295 len >= SHA256_BLOCK_SIZE;
296 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 msg += SHA256_BLOCK_SIZE,
298 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000299 uint32x4_t tmp, abcd_prev;
300
301 uint32x4_t abcd_orig = abcd;
302 uint32x4_t efgh_orig = efgh;
303
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
305 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
306 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
307 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000308
309#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
310 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
312 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
313 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
314 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000315#endif
316
317 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000319 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
321 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000322
323 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000325 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
327 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000328
329 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000331 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
333 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334
335 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000337 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
339 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000342 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
344 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000345 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
347 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000348
349 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
351 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
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 + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
358 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 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 t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
365 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
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
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 abcd = vaddq_u32(abcd, abcd_orig);
372 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000373 }
374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 vst1q_u32(&ctx->state[0], abcd);
376 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000379}
380
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100381#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
382/*
383 * This function is for internal use only if we are building both C and A64
384 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
385 */
386static
387#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100388int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
389 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000390{
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
392 SHA256_BLOCK_SIZE) ==
393 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000394}
395
Jerry Yu92fc5382023-02-16 11:17:11 +0800396#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800397#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800398#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800399#elif defined(__GNUC__)
400#pragma GCC pop_options
401#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800402#undef MBEDTLS_POP_TARGET_PRAGMA
403#endif
404
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000405#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
406
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000407#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
408#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
409#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
410#endif
411
412
413#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
414 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
417#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
420#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
423#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
426#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200428#define R(t) \
429 ( \
430 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
431 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100432 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Gilles Peskine449bd832023-01-11 14:50:10 +0100434#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200435 do \
436 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
438 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200439 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100442#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
443/*
444 * This function is for internal use only if we are building both C and A64
445 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
446 */
447static
448#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100449int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
450 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200451{
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200453 uint32_t temp1, temp2, W[64];
454 uint32_t A[8];
455 } local;
456
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200457 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200460 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200462
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200463#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 for (i = 0; i < 64; i++) {
465 if (i < 16) {
466 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
467 } else {
468 R(i);
469 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
472 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200473
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200474 local.temp1 = local.A[7]; local.A[7] = local.A[6];
475 local.A[6] = local.A[5]; local.A[5] = local.A[4];
476 local.A[4] = local.A[3]; local.A[3] = local.A[2];
477 local.A[2] = local.A[1]; local.A[1] = local.A[0];
478 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200479 }
480#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 for (i = 0; i < 16; i++) {
482 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200483 }
484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 for (i = 0; i < 16; i += 8) {
486 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
487 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
488 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
489 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
490 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
491 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
492 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
493 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
494 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
495 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
496 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
497 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
498 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
499 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
500 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
501 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
502 }
503
504 for (i = 16; i < 64; i += 8) {
505 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
506 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
507 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
508 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
509 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
510 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
511 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
512 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
513 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
514 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
515 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
516 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
517 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
518 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
519 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
520 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200521 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200522#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200523
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200525 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100527
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200528 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000532}
Jaeden Amero041039f2018-02-19 15:28:08 +0000533
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000534#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
535
536
537#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
538
539static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000541{
542 size_t processed = 0;
543
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 while (len >= SHA256_BLOCK_SIZE) {
545 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
546 return 0;
547 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000548
549 data += SHA256_BLOCK_SIZE;
550 len -= SHA256_BLOCK_SIZE;
551
552 processed += SHA256_BLOCK_SIZE;
553 }
554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000556}
557
558#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
559
560
561#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000564{
565 static int done = 0;
566 static int supported = 0;
567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000569 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000570 done = 1;
571 }
572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000574}
575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
577 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000578{
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 if (mbedtls_a64_crypto_sha256_has_support()) {
580 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
581 } else {
582 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
583 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000584}
585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
587 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000588{
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 if (mbedtls_a64_crypto_sha256_has_support()) {
590 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
591 } else {
592 return mbedtls_internal_sha256_process_c(ctx, data);
593 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000594}
595
596#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
597
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
599/*
600 * SHA-256 process buffer
601 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100602int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
603 const unsigned char *input,
604 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000605{
Janos Follath24eed8d2019-11-22 13:21:35 +0000606 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000607 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000608 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 if (ilen == 0) {
611 return 0;
612 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000615 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Paul Bakker5c2364c2012-10-01 14:41:15 +0000617 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618 ctx->total[0] &= 0xFFFFFFFF;
619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000621 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 if (left && ilen >= fill) {
625 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
628 return ret;
629 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100630
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 input += fill;
632 ilen -= fill;
633 left = 0;
634 }
635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000637 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 mbedtls_internal_sha256_process_many(ctx, input, ilen);
639 if (processed < SHA256_BLOCK_SIZE) {
640 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
641 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100642
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000643 input += processed;
644 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000645 }
646
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if (ilen > 0) {
648 memcpy((void *) (ctx->buffer + left), input, ilen);
649 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000652}
653
Paul Bakker5121ce52009-01-03 21:22:43 +0000654/*
655 * SHA-256 final digest
656 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100657int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
658 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000659{
Janos Follath24eed8d2019-11-22 13:21:35 +0000660 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200661 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000662 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000663
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200664 /*
665 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
666 */
667 used = ctx->total[0] & 0x3F;
668
669 ctx->buffer[used++] = 0x80;
670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200672 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 memset(ctx->buffer + used, 0, 56 - used);
674 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200675 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
679 return ret;
680 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200683 }
684
685 /*
686 * Add message length
687 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 high = (ctx->total[0] >> 29)
689 | (ctx->total[1] << 3);
690 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
693 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
696 return ret;
697 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100698
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200699 /*
700 * Output final state
701 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
703 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
704 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
705 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
706 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
707 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
708 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
David Horstmann687262c2022-10-06 17:54:57 +0100710 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200711#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100712 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200713#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 if (!truncated) {
715 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
716 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000719}
720
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200722
Paul Bakker5121ce52009-01-03 21:22:43 +0000723/*
724 * output = SHA-256( input buffer )
725 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100726int mbedtls_sha256(const unsigned char *input,
727 size_t ilen,
728 unsigned char *output,
729 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000730{
Janos Follath24eed8d2019-11-22 13:21:35 +0000731 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000733
Valerio Settia3f99592022-12-14 10:56:54 +0100734#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100736 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 }
Valerio Settia3f99592022-12-14 10:56:54 +0100738#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100740 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 }
Valerio Settia3f99592022-12-14 10:56:54 +0100742#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100744 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200746#endif
747
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100751 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100753
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100755 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100757
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100759 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100761
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100762exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000766}
767
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000769/*
770 * FIPS-180-2 test vectors
771 */
Valerio Settia3f99592022-12-14 10:56:54 +0100772static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000773{
774 { "abc" },
775 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
776 { "" }
777};
778
Valerio Settia3f99592022-12-14 10:56:54 +0100779static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000780{
781 3, 56, 1000
782};
783
Valerio Settia3f99592022-12-14 10:56:54 +0100784typedef const unsigned char (sha_test_sum_t)[32];
785
786/*
787 * SHA-224 test vectors
788 */
789#if defined(MBEDTLS_SHA224_C)
790static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000791{
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
793 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
794 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
795 0xE3, 0x6C, 0x9D, 0xA7 },
796 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
797 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
798 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
799 0x52, 0x52, 0x25, 0x25 },
800 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
801 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
802 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100803 0x4E, 0xE7, 0xAD, 0x67 }
804};
805#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000806
Valerio Settia3f99592022-12-14 10:56:54 +0100807/*
808 * SHA-256 test vectors
809 */
810#if defined(MBEDTLS_SHA256_C)
811static sha_test_sum_t sha256_test_sum[] =
812{
Paul Bakker5121ce52009-01-03 21:22:43 +0000813 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
814 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
815 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
816 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
817 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
818 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
819 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
820 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
821 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
822 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
823 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
824 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
825};
Valerio Settia3f99592022-12-14 10:56:54 +0100826#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000827
828/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000829 * Checkup routine
830 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100831static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000832{
Valerio Settia3f99592022-12-14 10:56:54 +0100833 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500834 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200835 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200836 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000837
Valerio Settia3f99592022-12-14 10:56:54 +0100838#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100840#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100842#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100844#endif
845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 buf = mbedtls_calloc(1024, sizeof(unsigned char));
847 if (NULL == buf) {
848 if (verbose != 0) {
849 mbedtls_printf("Buffer allocation failed\n");
850 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500851
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500853 }
854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200856
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 for (i = 0; i < 3; i++) {
858 if (verbose != 0) {
859 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
860 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100863 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 if (i == 2) {
867 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 for (int j = 0; j < 1000; j++) {
870 ret = mbedtls_sha256_update(&ctx, buf, buflen);
871 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100872 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100874 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100875
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 } else {
877 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
878 sha_test_buflen[i]);
879 if (ret != 0) {
880 goto fail;
881 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100882 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100885 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100887
Paul Bakker5121ce52009-01-03 21:22:43 +0000888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100890 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100891 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100892 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 if (verbose != 0) {
895 mbedtls_printf("passed\n");
896 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000897 }
898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 if (verbose != 0) {
900 mbedtls_printf("\n");
901 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100903 goto exit;
904
905fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 if (verbose != 0) {
907 mbedtls_printf("failed\n");
908 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100909
Paul Bakker5b4af392014-06-26 12:09:34 +0200910exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 mbedtls_sha256_free(&ctx);
912 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000915}
916
Valerio Settia3f99592022-12-14 10:56:54 +0100917#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100918int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100919{
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100921}
922#endif /* MBEDTLS_SHA256_C */
923
924#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100925int mbedtls_sha224_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, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100928}
929#endif /* MBEDTLS_SHA224_C */
930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000932
Valerio Settia3f99592022-12-14 10:56:54 +0100933#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */