blob: d5be7aa19c9eb5cf393319742d3dfffc3a746aa4 [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
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Valerio Settia3f99592022-12-14 10:56:54 +010027#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <string.h>
34
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010036
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000037#if defined(__aarch64__)
38# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010039 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080040/* *INDENT-OFF* */
41# if !defined(__ARM_FEATURE_CRYPTO)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080042# if defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080043# if __clang_major__ < 4
44# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
45# elif __clang_major__ < 18
Jerry Yu64e5d4a2023-02-15 11:46:57 +080046 /* TODO: Re-consider above after https://reviews.llvm.org/D131064
47 * merged.
48 *
49 * The intrinsic declaration are guarded with ACLE predefined macros
50 * in clang, and those macros are only enabled with command line.
51 * Define the macros can enable those declaration and avoid compile
52 * error on it.
53 */
54# define __ARM_FEATURE_CRYPTO 1
55# endif
56# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
57# define MBEDTLS_POP_TARGET_PRAGMA
58# elif defined(__GNUC__)
Jerry Yu8ae6a012023-02-16 15:16:20 +080059 /* FIXME: GCC-5 annouce crypto extension, but some intrinsic are missed.
60 * Known miss intrinsic can be workaround.
61 */
62# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080063# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
64# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080065# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080066# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080067# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080068# endif
69# else
70# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
71# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080072# endif
73/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000074# include <arm_neon.h>
75# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000076# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
77# if defined(__unix__)
78# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010079/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000080# include <sys/auxv.h>
81# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010082/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000083# include <signal.h>
84# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000085# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000086#elif defined(_M_ARM64)
87# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010088 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000089# include <arm64_neon.h>
90# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000091#else
92# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
93# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
94#endif
95
96#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
97/*
98 * Capability detection code comes early, so we can disable
99 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
100 */
101#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100102static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000103{
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000105}
106#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100107static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000108{
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000110}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000111#elif defined(_M_ARM64)
112#define WIN32_LEAN_AND_MEAN
113#include <Windows.h>
114#include <processthreadsapi.h>
115
Gilles Peskine449bd832023-01-11 14:50:10 +0100116static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000117{
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
119 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000120}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000121#elif defined(__unix__) && defined(SIG_SETMASK)
122/* Detection with SIGILL, setjmp() and longjmp() */
123#include <signal.h>
124#include <setjmp.h>
125
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000126static jmp_buf return_from_sigill;
127
128/*
129 * A64 SHA256 support detection via SIGILL
130 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100131static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000132{
133 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000135}
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000138{
139 struct sigaction old_action, new_action;
140
141 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 if (sigprocmask(0, NULL, &old_mask)) {
143 return 0;
144 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000147 new_action.sa_flags = 0;
148 new_action.sa_handler = sigill_handler;
149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000151
152 static int ret = 0;
153
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000155 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000157 ret = 1;
158 }
159
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 sigaction(SIGILL, &old_action, NULL);
161 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000162
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000164}
165#else
166#warning "No mechanism to detect A64_CRYPTO found, using C code only"
167#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
168#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
169
170#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
171
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200172#if !defined(MBEDTLS_SHA256_ALT)
173
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000174#define SHA256_BLOCK_SIZE 64
175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200177{
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200179}
180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200182{
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200184 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200188}
189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
191 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200192{
193 *dst = *src;
194}
195
Paul Bakker5121ce52009-01-03 21:22:43 +0000196/*
197 * SHA-256 context setup
198 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100199int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000200{
Valerio Settia3f99592022-12-14 10:56:54 +0100201#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100203 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 }
Valerio Settia3f99592022-12-14 10:56:54 +0100205#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100207 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 }
Valerio Settia3f99592022-12-14 10:56:54 +0100209#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100211 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200213#endif
214
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 ctx->total[0] = 0;
216 ctx->total[1] = 0;
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100219#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000220 ctx->state[0] = 0x6A09E667;
221 ctx->state[1] = 0xBB67AE85;
222 ctx->state[2] = 0x3C6EF372;
223 ctx->state[3] = 0xA54FF53A;
224 ctx->state[4] = 0x510E527F;
225 ctx->state[5] = 0x9B05688C;
226 ctx->state[6] = 0x1F83D9AB;
227 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100228#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200230#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000231 ctx->state[0] = 0xC1059ED8;
232 ctx->state[1] = 0x367CD507;
233 ctx->state[2] = 0x3070DD17;
234 ctx->state[3] = 0xF70E5939;
235 ctx->state[4] = 0xFFC00B31;
236 ctx->state[5] = 0x68581511;
237 ctx->state[6] = 0x64F98FA7;
238 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200239#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 }
241
Valerio Settia3f99592022-12-14 10:56:54 +0100242#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000243 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100244#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100245
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000247}
248
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200250static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000251{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200252 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
253 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
254 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
255 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
256 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
257 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
258 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
259 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
260 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
261 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
262 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
263 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
264 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
265 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
266 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
267 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
268};
Paul Bakker5121ce52009-01-03 21:22:43 +0000269
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000270#endif
271
272#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
273 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
274
275#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
276# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
277# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
278#endif
279
280static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000282{
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
284 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000285
286 size_t processed = 0;
287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000289 len >= SHA256_BLOCK_SIZE;
290 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 msg += SHA256_BLOCK_SIZE,
292 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000293 uint32x4_t tmp, abcd_prev;
294
295 uint32x4_t abcd_orig = abcd;
296 uint32x4_t efgh_orig = efgh;
297
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
299 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
300 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
301 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000302
303#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
304 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
306 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
307 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
308 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000309#endif
310
311 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000313 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
315 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000316
317 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
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 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
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 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
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
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000336 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
338 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000339 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
341 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000342
343 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
345 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000346 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
348 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000349
350 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
352 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000353 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
355 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000356
357 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
359 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000360 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
362 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000363 }
364
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 abcd = vaddq_u32(abcd, abcd_orig);
366 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000367 }
368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 vst1q_u32(&ctx->state[0], abcd);
370 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000373}
374
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100375#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
376/*
377 * This function is for internal use only if we are building both C and A64
378 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
379 */
380static
381#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100382int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
383 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000384{
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
386 SHA256_BLOCK_SIZE) ==
387 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000388}
389
Jerry Yu92fc5382023-02-16 11:17:11 +0800390#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800391#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800392#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800393#elif defined(__GNUC__)
394#pragma GCC pop_options
395#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800396#undef MBEDTLS_POP_TARGET_PRAGMA
397#endif
398
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000399#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
400
401
402#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
403#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
404#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
405#endif
406
407
408#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
409 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
412#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
415#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
418#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
421#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200423#define R(t) \
424 ( \
425 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
426 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100427 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200430 do \
431 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
433 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200434 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100437#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
438/*
439 * This function is for internal use only if we are building both C and A64
440 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
441 */
442static
443#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100444int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
445 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200446{
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200448 uint32_t temp1, temp2, W[64];
449 uint32_t A[8];
450 } local;
451
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200452 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200455 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200457
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200458#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 for (i = 0; i < 64; i++) {
460 if (i < 16) {
461 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
462 } else {
463 R(i);
464 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
467 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200468
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200469 local.temp1 = local.A[7]; local.A[7] = local.A[6];
470 local.A[6] = local.A[5]; local.A[5] = local.A[4];
471 local.A[4] = local.A[3]; local.A[3] = local.A[2];
472 local.A[2] = local.A[1]; local.A[1] = local.A[0];
473 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200474 }
475#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 for (i = 0; i < 16; i++) {
477 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200478 }
479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 for (i = 0; i < 16; i += 8) {
481 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
482 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
483 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
484 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
485 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
486 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
487 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
488 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
489 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
490 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
491 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
492 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
493 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
494 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
495 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
496 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
497 }
498
499 for (i = 16; i < 64; i += 8) {
500 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
501 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
502 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
503 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
504 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
505 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
506 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
507 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
508 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
509 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
510 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
511 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
512 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
513 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
514 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
515 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200516 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200517#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200520 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100522
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200523 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100525
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000527}
Jaeden Amero041039f2018-02-19 15:28:08 +0000528
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000529#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
530
531
532#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
533
534static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000536{
537 size_t processed = 0;
538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 while (len >= SHA256_BLOCK_SIZE) {
540 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
541 return 0;
542 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000543
544 data += SHA256_BLOCK_SIZE;
545 len -= SHA256_BLOCK_SIZE;
546
547 processed += SHA256_BLOCK_SIZE;
548 }
549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000551}
552
553#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
554
555
556#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000559{
560 static int done = 0;
561 static int supported = 0;
562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000564 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000565 done = 1;
566 }
567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000569}
570
Gilles Peskine449bd832023-01-11 14:50:10 +0100571static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
572 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000573{
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 if (mbedtls_a64_crypto_sha256_has_support()) {
575 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
576 } else {
577 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
578 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000579}
580
Gilles Peskine449bd832023-01-11 14:50:10 +0100581int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
582 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000583{
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 if (mbedtls_a64_crypto_sha256_has_support()) {
585 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
586 } else {
587 return mbedtls_internal_sha256_process_c(ctx, data);
588 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000589}
590
591#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
592
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594/*
595 * SHA-256 process buffer
596 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100597int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
598 const unsigned char *input,
599 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000600{
Janos Follath24eed8d2019-11-22 13:21:35 +0000601 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000602 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000603 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 if (ilen == 0) {
606 return 0;
607 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
609 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000610 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
Paul Bakker5c2364c2012-10-01 14:41:15 +0000612 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000613 ctx->total[0] &= 0xFFFFFFFF;
614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000616 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 if (left && ilen >= fill) {
620 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100621
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
623 return ret;
624 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100625
Paul Bakker5121ce52009-01-03 21:22:43 +0000626 input += fill;
627 ilen -= fill;
628 left = 0;
629 }
630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000632 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 mbedtls_internal_sha256_process_many(ctx, input, ilen);
634 if (processed < SHA256_BLOCK_SIZE) {
635 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
636 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100637
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000638 input += processed;
639 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 }
641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 if (ilen > 0) {
643 memcpy((void *) (ctx->buffer + left), input, ilen);
644 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100645
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000647}
648
Paul Bakker5121ce52009-01-03 21:22:43 +0000649/*
650 * SHA-256 final digest
651 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100652int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
653 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000654{
Janos Follath24eed8d2019-11-22 13:21:35 +0000655 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200656 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000657 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000658
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200659 /*
660 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
661 */
662 used = ctx->total[0] & 0x3F;
663
664 ctx->buffer[used++] = 0x80;
665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200667 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 memset(ctx->buffer + used, 0, 56 - used);
669 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200670 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200672
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
674 return ret;
675 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200676
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200678 }
679
680 /*
681 * Add message length
682 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 high = (ctx->total[0] >> 29)
684 | (ctx->total[1] << 3);
685 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
688 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
691 return ret;
692 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100693
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200694 /*
695 * Output final state
696 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
698 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
699 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
700 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
701 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
702 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
703 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000704
David Horstmann687262c2022-10-06 17:54:57 +0100705 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200706#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100707 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200708#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 if (!truncated) {
710 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
711 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000714}
715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200717
Paul Bakker5121ce52009-01-03 21:22:43 +0000718/*
719 * output = SHA-256( input buffer )
720 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100721int mbedtls_sha256(const unsigned char *input,
722 size_t ilen,
723 unsigned char *output,
724 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000725{
Janos Follath24eed8d2019-11-22 13:21:35 +0000726 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200727 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000728
Valerio Settia3f99592022-12-14 10:56:54 +0100729#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100731 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 }
Valerio Settia3f99592022-12-14 10:56:54 +0100733#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100735 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 }
Valerio Settia3f99592022-12-14 10:56:54 +0100737#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100739 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200741#endif
742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100744
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100746 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100750 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100754 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100756
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100757exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000761}
762
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000764/*
765 * FIPS-180-2 test vectors
766 */
Valerio Settia3f99592022-12-14 10:56:54 +0100767static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000768{
769 { "abc" },
770 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
771 { "" }
772};
773
Valerio Settia3f99592022-12-14 10:56:54 +0100774static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000775{
776 3, 56, 1000
777};
778
Valerio Settia3f99592022-12-14 10:56:54 +0100779typedef const unsigned char (sha_test_sum_t)[32];
780
781/*
782 * SHA-224 test vectors
783 */
784#if defined(MBEDTLS_SHA224_C)
785static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000786{
Paul Bakker5121ce52009-01-03 21:22:43 +0000787 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
788 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
789 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
790 0xE3, 0x6C, 0x9D, 0xA7 },
791 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
792 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
793 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
794 0x52, 0x52, 0x25, 0x25 },
795 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
796 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
797 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100798 0x4E, 0xE7, 0xAD, 0x67 }
799};
800#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000801
Valerio Settia3f99592022-12-14 10:56:54 +0100802/*
803 * SHA-256 test vectors
804 */
805#if defined(MBEDTLS_SHA256_C)
806static sha_test_sum_t sha256_test_sum[] =
807{
Paul Bakker5121ce52009-01-03 21:22:43 +0000808 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
809 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
810 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
811 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
812 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
813 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
814 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
815 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
816 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
817 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
818 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
819 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
820};
Valerio Settia3f99592022-12-14 10:56:54 +0100821#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000822
823/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000824 * Checkup routine
825 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100826static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000827{
Valerio Settia3f99592022-12-14 10:56:54 +0100828 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500829 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200830 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200831 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000832
Valerio Settia3f99592022-12-14 10:56:54 +0100833#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100835#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100837#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100839#endif
840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 buf = mbedtls_calloc(1024, sizeof(unsigned char));
842 if (NULL == buf) {
843 if (verbose != 0) {
844 mbedtls_printf("Buffer allocation failed\n");
845 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500848 }
849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200851
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 for (i = 0; i < 3; i++) {
853 if (verbose != 0) {
854 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
855 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000856
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100858 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 if (i == 2) {
862 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 for (int j = 0; j < 1000; j++) {
865 ret = mbedtls_sha256_update(&ctx, buf, buflen);
866 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100867 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100869 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100870
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 } else {
872 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
873 sha_test_buflen[i]);
874 if (ret != 0) {
875 goto fail;
876 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100877 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100880 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 }
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 (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100885 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100886 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100887 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 if (verbose != 0) {
890 mbedtls_printf("passed\n");
891 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000892 }
893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 if (verbose != 0) {
895 mbedtls_printf("\n");
896 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000897
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100898 goto exit;
899
900fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 if (verbose != 0) {
902 mbedtls_printf("failed\n");
903 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100904
Paul Bakker5b4af392014-06-26 12:09:34 +0200905exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 mbedtls_sha256_free(&ctx);
907 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000910}
911
Valerio Settia3f99592022-12-14 10:56:54 +0100912#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100913int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100914{
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100916}
917#endif /* MBEDTLS_SHA256_C */
918
919#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100920int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100921{
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100923}
924#endif /* MBEDTLS_SHA224_C */
925
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000927
Valerio Settia3f99592022-12-14 10:56:54 +0100928#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */