blob: bf9af6b5a9d0771fee2585f548831716e143e6c3 [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__)
43# if __clang_major__ < 18
44 /* TODO: Re-consider above after https://reviews.llvm.org/D131064
45 * merged.
46 *
47 * The intrinsic declaration are guarded with ACLE predefined macros
48 * in clang, and those macros are only enabled with command line.
49 * Define the macros can enable those declaration and avoid compile
50 * error on it.
51 */
52# define __ARM_FEATURE_CRYPTO 1
53# endif
54# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
55# define MBEDTLS_POP_TARGET_PRAGMA
56# elif defined(__GNUC__)
Jerry Yu8ae6a012023-02-16 15:16:20 +080057 /* FIXME: GCC-5 annouce crypto extension, but some intrinsic are missed.
58 * Known miss intrinsic can be workaround.
59 */
60# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080061# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
62# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080063# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080064# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080065# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080066# endif
67# else
68# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
69# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080070# endif
71/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000072# include <arm_neon.h>
73# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000074# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
75# if defined(__unix__)
76# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010077/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000078# include <sys/auxv.h>
79# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010080/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000081# include <signal.h>
82# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000083# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000084#elif defined(_M_ARM64)
85# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010086 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000087# include <arm64_neon.h>
88# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000089#else
90# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
91# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
92#endif
93
94#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
95/*
96 * Capability detection code comes early, so we can disable
97 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
98 */
99#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100100static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000101{
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000103}
104#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100105static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000106{
Gilles Peskine449bd832023-01-11 14:50:10 +0100107 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000108}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000109#elif defined(_M_ARM64)
110#define WIN32_LEAN_AND_MEAN
111#include <Windows.h>
112#include <processthreadsapi.h>
113
Gilles Peskine449bd832023-01-11 14:50:10 +0100114static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000115{
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
117 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000118}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000119#elif defined(__unix__) && defined(SIG_SETMASK)
120/* Detection with SIGILL, setjmp() and longjmp() */
121#include <signal.h>
122#include <setjmp.h>
123
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000124static jmp_buf return_from_sigill;
125
126/*
127 * A64 SHA256 support detection via SIGILL
128 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100129static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000130{
131 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000133}
134
Gilles Peskine449bd832023-01-11 14:50:10 +0100135static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000136{
137 struct sigaction old_action, new_action;
138
139 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 if (sigprocmask(0, NULL, &old_mask)) {
141 return 0;
142 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000143
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000145 new_action.sa_flags = 0;
146 new_action.sa_handler = sigill_handler;
147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000149
150 static int ret = 0;
151
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000153 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000155 ret = 1;
156 }
157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 sigaction(SIGILL, &old_action, NULL);
159 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000160
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000162}
163#else
164#warning "No mechanism to detect A64_CRYPTO found, using C code only"
165#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
166#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
167
168#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
169
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200170#if !defined(MBEDTLS_SHA256_ALT)
171
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000172#define SHA256_BLOCK_SIZE 64
173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200175{
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200177}
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200180{
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200182 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200186}
187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
189 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200190{
191 *dst = *src;
192}
193
Paul Bakker5121ce52009-01-03 21:22:43 +0000194/*
195 * SHA-256 context setup
196 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100197int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000198{
Valerio Settia3f99592022-12-14 10:56:54 +0100199#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100201 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 }
Valerio Settia3f99592022-12-14 10:56:54 +0100203#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100205 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 }
Valerio Settia3f99592022-12-14 10:56:54 +0100207#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100209 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200211#endif
212
Paul Bakker5121ce52009-01-03 21:22:43 +0000213 ctx->total[0] = 0;
214 ctx->total[1] = 0;
215
Gilles Peskine449bd832023-01-11 14:50:10 +0100216 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100217#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000218 ctx->state[0] = 0x6A09E667;
219 ctx->state[1] = 0xBB67AE85;
220 ctx->state[2] = 0x3C6EF372;
221 ctx->state[3] = 0xA54FF53A;
222 ctx->state[4] = 0x510E527F;
223 ctx->state[5] = 0x9B05688C;
224 ctx->state[6] = 0x1F83D9AB;
225 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100226#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200228#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000229 ctx->state[0] = 0xC1059ED8;
230 ctx->state[1] = 0x367CD507;
231 ctx->state[2] = 0x3070DD17;
232 ctx->state[3] = 0xF70E5939;
233 ctx->state[4] = 0xFFC00B31;
234 ctx->state[5] = 0x68581511;
235 ctx->state[6] = 0x64F98FA7;
236 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200237#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000238 }
239
Valerio Settia3f99592022-12-14 10:56:54 +0100240#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000241 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100242#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000245}
246
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200247#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200248static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000249{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200250 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
251 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
252 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
253 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
254 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
255 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
256 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
257 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
258 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
259 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
260 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
261 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
262 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
263 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
264 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
265 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
266};
Paul Bakker5121ce52009-01-03 21:22:43 +0000267
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000268#endif
269
270#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
271 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
272
273#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
274# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
275# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
276#endif
277
278static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000280{
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
282 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000283
284 size_t processed = 0;
285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000287 len >= SHA256_BLOCK_SIZE;
288 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 msg += SHA256_BLOCK_SIZE,
290 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000291 uint32x4_t tmp, abcd_prev;
292
293 uint32x4_t abcd_orig = abcd;
294 uint32x4_t efgh_orig = efgh;
295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
297 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
298 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
299 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000300
301#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
302 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
304 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
305 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
306 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000307#endif
308
309 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000311 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
313 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000314
315 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000317 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
319 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000320
321 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000323 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
325 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000326
327 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000329 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
331 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
336 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
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
341 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
343 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000344 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
346 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000347
348 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
350 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000351 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
353 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000354
355 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
357 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000358 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
360 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000361 }
362
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 abcd = vaddq_u32(abcd, abcd_orig);
364 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000365 }
366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 vst1q_u32(&ctx->state[0], abcd);
368 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000369
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000371}
372
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100373#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
374/*
375 * This function is for internal use only if we are building both C and A64
376 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
377 */
378static
379#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100380int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
381 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000382{
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
384 SHA256_BLOCK_SIZE) ==
385 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000386}
387
Jerry Yu92fc5382023-02-16 11:17:11 +0800388#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800389#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800390#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800391#elif defined(__GNUC__)
392#pragma GCC pop_options
393#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800394#undef MBEDTLS_POP_TARGET_PRAGMA
395#endif
396
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000397#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
398
399
400#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
401#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
402#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
403#endif
404
405
406#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
407 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
410#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
413#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
416#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
419#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200421#define R(t) \
422 ( \
423 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
424 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100425 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200428 do \
429 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
431 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200432 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100435#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
436/*
437 * This function is for internal use only if we are building both C and A64
438 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
439 */
440static
441#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100442int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
443 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200444{
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200446 uint32_t temp1, temp2, W[64];
447 uint32_t A[8];
448 } local;
449
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200450 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200453 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200455
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200456#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 for (i = 0; i < 64; i++) {
458 if (i < 16) {
459 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
460 } else {
461 R(i);
462 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
465 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200466
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200467 local.temp1 = local.A[7]; local.A[7] = local.A[6];
468 local.A[6] = local.A[5]; local.A[5] = local.A[4];
469 local.A[4] = local.A[3]; local.A[3] = local.A[2];
470 local.A[2] = local.A[1]; local.A[1] = local.A[0];
471 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200472 }
473#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 for (i = 0; i < 16; i++) {
475 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200476 }
477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 for (i = 0; i < 16; i += 8) {
479 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
480 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
481 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
482 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
483 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
484 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
485 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
486 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
487 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
488 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
489 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
490 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
491 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
492 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
493 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
494 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
495 }
496
497 for (i = 16; i < 64; i += 8) {
498 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
499 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
500 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
501 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
502 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
503 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
504 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
505 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
506 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
507 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
508 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
509 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
510 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
511 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
512 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
513 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200514 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200515#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200516
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200518 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100520
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200521 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100523
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000525}
Jaeden Amero041039f2018-02-19 15:28:08 +0000526
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000527#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
528
529
530#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
531
532static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000534{
535 size_t processed = 0;
536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 while (len >= SHA256_BLOCK_SIZE) {
538 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
539 return 0;
540 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000541
542 data += SHA256_BLOCK_SIZE;
543 len -= SHA256_BLOCK_SIZE;
544
545 processed += SHA256_BLOCK_SIZE;
546 }
547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000549}
550
551#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
552
553
554#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000557{
558 static int done = 0;
559 static int supported = 0;
560
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000562 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000563 done = 1;
564 }
565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000567}
568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
570 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000571{
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if (mbedtls_a64_crypto_sha256_has_support()) {
573 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
574 } else {
575 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
576 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000577}
578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
580 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000581{
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 if (mbedtls_a64_crypto_sha256_has_support()) {
583 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
584 } else {
585 return mbedtls_internal_sha256_process_c(ctx, data);
586 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000587}
588
589#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
590
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
592/*
593 * SHA-256 process buffer
594 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100595int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
596 const unsigned char *input,
597 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000598{
Janos Follath24eed8d2019-11-22 13:21:35 +0000599 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000600 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000601 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 if (ilen == 0) {
604 return 0;
605 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
607 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000608 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Paul Bakker5c2364c2012-10-01 14:41:15 +0000610 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000611 ctx->total[0] &= 0xFFFFFFFF;
612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000614 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 if (left && ilen >= fill) {
618 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
621 return ret;
622 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100623
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 input += fill;
625 ilen -= fill;
626 left = 0;
627 }
628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000630 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 mbedtls_internal_sha256_process_many(ctx, input, ilen);
632 if (processed < SHA256_BLOCK_SIZE) {
633 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
634 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100635
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000636 input += processed;
637 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 }
639
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (ilen > 0) {
641 memcpy((void *) (ctx->buffer + left), input, ilen);
642 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000645}
646
Paul Bakker5121ce52009-01-03 21:22:43 +0000647/*
648 * SHA-256 final digest
649 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100650int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
651 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000652{
Janos Follath24eed8d2019-11-22 13:21:35 +0000653 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200654 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000655 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200657 /*
658 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
659 */
660 used = ctx->total[0] & 0x3F;
661
662 ctx->buffer[used++] = 0x80;
663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200665 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 memset(ctx->buffer + used, 0, 56 - used);
667 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200668 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
672 return ret;
673 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200676 }
677
678 /*
679 * Add message length
680 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 high = (ctx->total[0] >> 29)
682 | (ctx->total[1] << 3);
683 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
686 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
689 return ret;
690 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100691
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200692 /*
693 * Output final state
694 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
696 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
697 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
698 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
699 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
700 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
701 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000702
David Horstmann687262c2022-10-06 17:54:57 +0100703 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200704#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100705 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200706#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 if (!truncated) {
708 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
709 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000712}
713
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200715
Paul Bakker5121ce52009-01-03 21:22:43 +0000716/*
717 * output = SHA-256( input buffer )
718 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100719int mbedtls_sha256(const unsigned char *input,
720 size_t ilen,
721 unsigned char *output,
722 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000723{
Janos Follath24eed8d2019-11-22 13:21:35 +0000724 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000726
Valerio Settia3f99592022-12-14 10:56:54 +0100727#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100729 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 }
Valerio Settia3f99592022-12-14 10:56:54 +0100731#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100733 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 }
Valerio Settia3f99592022-12-14 10:56:54 +0100735#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100737 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200739#endif
740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100744 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100748 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100752 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100754
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100755exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100757
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000759}
760
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000762/*
763 * FIPS-180-2 test vectors
764 */
Valerio Settia3f99592022-12-14 10:56:54 +0100765static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000766{
767 { "abc" },
768 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
769 { "" }
770};
771
Valerio Settia3f99592022-12-14 10:56:54 +0100772static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000773{
774 3, 56, 1000
775};
776
Valerio Settia3f99592022-12-14 10:56:54 +0100777typedef const unsigned char (sha_test_sum_t)[32];
778
779/*
780 * SHA-224 test vectors
781 */
782#if defined(MBEDTLS_SHA224_C)
783static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000784{
Paul Bakker5121ce52009-01-03 21:22:43 +0000785 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
786 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
787 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
788 0xE3, 0x6C, 0x9D, 0xA7 },
789 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
790 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
791 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
792 0x52, 0x52, 0x25, 0x25 },
793 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
794 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
795 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100796 0x4E, 0xE7, 0xAD, 0x67 }
797};
798#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000799
Valerio Settia3f99592022-12-14 10:56:54 +0100800/*
801 * SHA-256 test vectors
802 */
803#if defined(MBEDTLS_SHA256_C)
804static sha_test_sum_t sha256_test_sum[] =
805{
Paul Bakker5121ce52009-01-03 21:22:43 +0000806 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
807 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
808 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
809 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
810 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
811 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
812 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
813 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
814 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
815 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
816 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
817 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
818};
Valerio Settia3f99592022-12-14 10:56:54 +0100819#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000820
821/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000822 * Checkup routine
823 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100824static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000825{
Valerio Settia3f99592022-12-14 10:56:54 +0100826 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500827 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200828 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000830
Valerio Settia3f99592022-12-14 10:56:54 +0100831#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100833#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100835#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100837#endif
838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 buf = mbedtls_calloc(1024, sizeof(unsigned char));
840 if (NULL == buf) {
841 if (verbose != 0) {
842 mbedtls_printf("Buffer allocation failed\n");
843 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500846 }
847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 for (i = 0; i < 3; i++) {
851 if (verbose != 0) {
852 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
853 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100856 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 if (i == 2) {
860 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 for (int j = 0; j < 1000; j++) {
863 ret = mbedtls_sha256_update(&ctx, buf, buflen);
864 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100865 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100867 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 } else {
870 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
871 sha_test_buflen[i]);
872 if (ret != 0) {
873 goto fail;
874 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100875 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100878 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100880
Paul Bakker5121ce52009-01-03 21:22:43 +0000881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100883 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100884 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100885 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 if (verbose != 0) {
888 mbedtls_printf("passed\n");
889 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000890 }
891
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 if (verbose != 0) {
893 mbedtls_printf("\n");
894 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000895
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100896 goto exit;
897
898fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 if (verbose != 0) {
900 mbedtls_printf("failed\n");
901 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100902
Paul Bakker5b4af392014-06-26 12:09:34 +0200903exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 mbedtls_sha256_free(&ctx);
905 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000908}
909
Valerio Settia3f99592022-12-14 10:56:54 +0100910#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100911int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100912{
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100914}
915#endif /* MBEDTLS_SHA256_C */
916
917#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100918int mbedtls_sha224_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, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100921}
922#endif /* MBEDTLS_SHA224_C */
923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000925
Valerio Settia3f99592022-12-14 10:56:54 +0100926#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */