blob: 605b2b041ffb94df11b7a26e495c0dbeacc9915e [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Jerry Yua135dee2023-02-16 16:56:22 +080025#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
26 defined(__clang__) && __clang_major__ < 18 && __clang_major__ > 3
27/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
28 *
Jerry Yufc2e1282023-02-27 11:16:56 +080029 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
30 * these are normally only enabled by the -march option on the command line.
31 * By defining the macros ourselves we gain access to those declarations without
32 * requiring -march on the command line.
Jerry Yu4d786a72023-02-22 11:01:07 +080033 *
Jerry Yufc2e1282023-02-27 11:16:56 +080034 * `arm_neon.h` could be included by any header file, so we put these defines
35 * at the top of this file, before any includes.
Jerry Yua135dee2023-02-16 16:56:22 +080036 */
37#define __ARM_FEATURE_CRYPTO 1
Jerry Yu4d786a72023-02-22 11:01:07 +080038#define NEED_TARGET_OPTIONS
Jerry Yua135dee2023-02-16 16:56:22 +080039#endif /* __aarch64__ && __clang__ &&
Jerry Yuba4ec242023-02-21 15:59:13 +080040 !__ARM_FEATURE_CRYPTO && __clang_major__ < 18 && __clang_major__ > 3 */
Jerry Yua135dee2023-02-16 16:56:22 +080041
Gilles Peskinedb09ef62020-06-03 01:43:33 +020042#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000043
Valerio Settia3f99592022-12-14 10:56:54 +010044#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050047#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000048#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000049
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <string.h>
51
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000052#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000054#if defined(__aarch64__)
55# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010056 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Jerry Yu35f2b262023-02-15 11:35:55 +080057/* *INDENT-OFF* */
Jerry Yu4d786a72023-02-22 11:01:07 +080058# if !defined(__ARM_FEATURE_CRYPTO) || defined(NEED_TARGET_OPTIONS)
Jerry Yu64e5d4a2023-02-15 11:46:57 +080059# if defined(__clang__)
Jerry Yu383cbf42023-02-16 15:16:43 +080060# if __clang_major__ < 4
61# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
Jerry Yu64e5d4a2023-02-15 11:46:57 +080062# endif
63# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
64# define MBEDTLS_POP_TARGET_PRAGMA
65# elif defined(__GNUC__)
Tom Cosgrove5c8505f2023-03-07 11:39:52 +000066 /* FIXME: GCC-5 claims crypto extension, but some intrinsic are missed.
Jerry Yu8ae6a012023-02-16 15:16:20 +080067 * Known miss intrinsic can be workaround.
68 */
69# if __GNUC__ < 6
Jerry Yu64e5d4a2023-02-15 11:46:57 +080070# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
71# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080072# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080073# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080074# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080075# endif
76# else
77# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
78# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080079# endif
80/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000081# include <arm_neon.h>
82# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000083# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
84# if defined(__unix__)
85# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010086/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000087# include <sys/auxv.h>
88# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010089/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000090# include <signal.h>
91# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000092# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000093#elif defined(_M_ARM64)
94# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010095 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000096# include <arm64_neon.h>
97# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000098#else
99# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
100# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
101#endif
102
103#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
104/*
105 * Capability detection code comes early, so we can disable
106 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
107 */
108#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100109static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000110{
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000112}
113#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100114static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000115{
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000117}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000118#elif defined(_M_ARM64)
119#define WIN32_LEAN_AND_MEAN
120#include <Windows.h>
121#include <processthreadsapi.h>
122
Gilles Peskine449bd832023-01-11 14:50:10 +0100123static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000124{
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
126 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000127}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000128#elif defined(__unix__) && defined(SIG_SETMASK)
129/* Detection with SIGILL, setjmp() and longjmp() */
130#include <signal.h>
131#include <setjmp.h>
132
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000133static jmp_buf return_from_sigill;
134
135/*
136 * A64 SHA256 support detection via SIGILL
137 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100138static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000139{
140 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000142}
143
Gilles Peskine449bd832023-01-11 14:50:10 +0100144static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000145{
146 struct sigaction old_action, new_action;
147
148 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 if (sigprocmask(0, NULL, &old_mask)) {
150 return 0;
151 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000154 new_action.sa_flags = 0;
155 new_action.sa_handler = sigill_handler;
156
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000158
159 static int ret = 0;
160
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000162 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000164 ret = 1;
165 }
166
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 sigaction(SIGILL, &old_action, NULL);
168 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000171}
172#else
173#warning "No mechanism to detect A64_CRYPTO found, using C code only"
174#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
175#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
176
177#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
178
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200179#if !defined(MBEDTLS_SHA256_ALT)
180
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000181#define SHA256_BLOCK_SIZE 64
182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200184{
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200186}
187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200189{
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200191 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200195}
196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
198 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200199{
200 *dst = *src;
201}
202
Paul Bakker5121ce52009-01-03 21:22:43 +0000203/*
204 * SHA-256 context setup
205 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100206int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000207{
Valerio Settia3f99592022-12-14 10:56:54 +0100208#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100210 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 }
Valerio Settia3f99592022-12-14 10:56:54 +0100212#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100214 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 }
Valerio Settia3f99592022-12-14 10:56:54 +0100216#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100218 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200220#endif
221
Paul Bakker5121ce52009-01-03 21:22:43 +0000222 ctx->total[0] = 0;
223 ctx->total[1] = 0;
224
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100226#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 ctx->state[0] = 0x6A09E667;
228 ctx->state[1] = 0xBB67AE85;
229 ctx->state[2] = 0x3C6EF372;
230 ctx->state[3] = 0xA54FF53A;
231 ctx->state[4] = 0x510E527F;
232 ctx->state[5] = 0x9B05688C;
233 ctx->state[6] = 0x1F83D9AB;
234 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100235#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200237#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000238 ctx->state[0] = 0xC1059ED8;
239 ctx->state[1] = 0x367CD507;
240 ctx->state[2] = 0x3070DD17;
241 ctx->state[3] = 0xF70E5939;
242 ctx->state[4] = 0xFFC00B31;
243 ctx->state[5] = 0x68581511;
244 ctx->state[6] = 0x64F98FA7;
245 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200246#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000247 }
248
Valerio Settia3f99592022-12-14 10:56:54 +0100249#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000250 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100251#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000254}
255
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200257static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000258{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200259 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
260 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
261 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
262 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
263 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
264 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
265 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
266 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
267 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
268 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
269 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
270 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
271 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
272 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
273 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
274 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
275};
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000277#endif
278
279#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
280 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
281
282#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
283# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
284# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
285#endif
286
287static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000289{
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
291 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000292
293 size_t processed = 0;
294
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000296 len >= SHA256_BLOCK_SIZE;
297 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 msg += SHA256_BLOCK_SIZE,
299 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000300 uint32x4_t tmp, abcd_prev;
301
302 uint32x4_t abcd_orig = abcd;
303 uint32x4_t efgh_orig = efgh;
304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
306 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
307 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
308 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000309
310#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
311 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
313 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
314 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
315 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000316#endif
317
318 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000320 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
322 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000323
324 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000326 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
328 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000329
330 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000332 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
334 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000335
336 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000338 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
340 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000343 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
345 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
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 + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
352 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000353 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
355 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000356
357 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
359 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
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 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
366 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000367 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
369 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000370 }
371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 abcd = vaddq_u32(abcd, abcd_orig);
373 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000374 }
375
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 vst1q_u32(&ctx->state[0], abcd);
377 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000378
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000380}
381
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100382#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
383/*
384 * This function is for internal use only if we are building both C and A64
385 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
386 */
387static
388#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100389int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
390 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000391{
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
393 SHA256_BLOCK_SIZE) ==
394 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000395}
396
Jerry Yu92fc5382023-02-16 11:17:11 +0800397#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800398#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800399#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800400#elif defined(__GNUC__)
401#pragma GCC pop_options
402#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800403#undef MBEDTLS_POP_TARGET_PRAGMA
404#endif
405
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000406#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
407
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000408#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
409#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
410#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
411#endif
412
413
414#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
415 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
418#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
421#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
424#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
427#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200429#define R(t) \
430 ( \
431 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
432 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100433 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
Gilles Peskine449bd832023-01-11 14:50:10 +0100435#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200436 do \
437 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
439 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200440 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100443#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
444/*
445 * This function is for internal use only if we are building both C and A64
446 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
447 */
448static
449#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100450int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
451 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200452{
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200454 uint32_t temp1, temp2, W[64];
455 uint32_t A[8];
456 } local;
457
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200458 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200461 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200463
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200464#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 for (i = 0; i < 64; i++) {
466 if (i < 16) {
467 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
468 } else {
469 R(i);
470 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200471
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
473 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200474
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200475 local.temp1 = local.A[7]; local.A[7] = local.A[6];
476 local.A[6] = local.A[5]; local.A[5] = local.A[4];
477 local.A[4] = local.A[3]; local.A[3] = local.A[2];
478 local.A[2] = local.A[1]; local.A[1] = local.A[0];
479 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200480 }
481#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 for (i = 0; i < 16; i++) {
483 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200484 }
485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 for (i = 0; i < 16; i += 8) {
487 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
488 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
489 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
490 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
491 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
492 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
493 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
494 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
495 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
496 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
497 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
498 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
499 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
500 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
501 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
502 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
503 }
504
505 for (i = 16; i < 64; i += 8) {
506 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
507 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
508 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
509 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
510 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
511 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
512 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
513 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
514 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
515 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
516 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
517 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
518 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
519 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
520 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
521 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200522 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200523#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200524
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200526 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100528
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200529 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100531
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000533}
Jaeden Amero041039f2018-02-19 15:28:08 +0000534
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000535#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
536
537
538#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
539
540static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000542{
543 size_t processed = 0;
544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 while (len >= SHA256_BLOCK_SIZE) {
546 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
547 return 0;
548 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000549
550 data += SHA256_BLOCK_SIZE;
551 len -= SHA256_BLOCK_SIZE;
552
553 processed += SHA256_BLOCK_SIZE;
554 }
555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000557}
558
559#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
560
561
562#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000565{
566 static int done = 0;
567 static int supported = 0;
568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000570 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000571 done = 1;
572 }
573
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000575}
576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
578 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000579{
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 if (mbedtls_a64_crypto_sha256_has_support()) {
581 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
582 } else {
583 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
584 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000585}
586
Gilles Peskine449bd832023-01-11 14:50:10 +0100587int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
588 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000589{
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 if (mbedtls_a64_crypto_sha256_has_support()) {
591 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
592 } else {
593 return mbedtls_internal_sha256_process_c(ctx, data);
594 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000595}
596
597#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
598
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
600/*
601 * SHA-256 process buffer
602 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100603int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
604 const unsigned char *input,
605 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000606{
Janos Follath24eed8d2019-11-22 13:21:35 +0000607 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000608 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000609 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 if (ilen == 0) {
612 return 0;
613 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
615 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000616 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
Paul Bakker5c2364c2012-10-01 14:41:15 +0000618 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000619 ctx->total[0] &= 0xFFFFFFFF;
620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000622 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 if (left && ilen >= fill) {
626 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
629 return ret;
630 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100631
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 input += fill;
633 ilen -= fill;
634 left = 0;
635 }
636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000638 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 mbedtls_internal_sha256_process_many(ctx, input, ilen);
640 if (processed < SHA256_BLOCK_SIZE) {
641 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
642 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100643
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000644 input += processed;
645 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 }
647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 if (ilen > 0) {
649 memcpy((void *) (ctx->buffer + left), input, ilen);
650 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000653}
654
Paul Bakker5121ce52009-01-03 21:22:43 +0000655/*
656 * SHA-256 final digest
657 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100658int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
659 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000660{
Janos Follath24eed8d2019-11-22 13:21:35 +0000661 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200662 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000663 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200665 /*
666 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
667 */
668 used = ctx->total[0] & 0x3F;
669
670 ctx->buffer[used++] = 0x80;
671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200673 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 memset(ctx->buffer + used, 0, 56 - used);
675 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200676 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
680 return ret;
681 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200682
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200684 }
685
686 /*
687 * Add message length
688 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 high = (ctx->total[0] >> 29)
690 | (ctx->total[1] << 3);
691 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
694 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
697 return ret;
698 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100699
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200700 /*
701 * Output final state
702 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
704 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
705 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
706 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
707 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
708 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
709 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
David Horstmann687262c2022-10-06 17:54:57 +0100711 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200712#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100713 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200714#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 if (!truncated) {
716 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
717 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000720}
721
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200723
Paul Bakker5121ce52009-01-03 21:22:43 +0000724/*
725 * output = SHA-256( input buffer )
726 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100727int mbedtls_sha256(const unsigned char *input,
728 size_t ilen,
729 unsigned char *output,
730 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000731{
Janos Follath24eed8d2019-11-22 13:21:35 +0000732 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200733 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000734
Valerio Settia3f99592022-12-14 10:56:54 +0100735#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100737 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 }
Valerio Settia3f99592022-12-14 10:56:54 +0100739#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100741 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 }
Valerio Settia3f99592022-12-14 10:56:54 +0100743#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100745 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200747#endif
748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 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
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100756 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100758
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100760 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100762
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100763exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100765
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000767}
768
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000770/*
771 * FIPS-180-2 test vectors
772 */
Valerio Settia3f99592022-12-14 10:56:54 +0100773static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000774{
775 { "abc" },
776 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
777 { "" }
778};
779
Valerio Settia3f99592022-12-14 10:56:54 +0100780static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000781{
782 3, 56, 1000
783};
784
Valerio Settia3f99592022-12-14 10:56:54 +0100785typedef const unsigned char (sha_test_sum_t)[32];
786
787/*
788 * SHA-224 test vectors
789 */
790#if defined(MBEDTLS_SHA224_C)
791static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000792{
Paul Bakker5121ce52009-01-03 21:22:43 +0000793 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
794 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
795 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
796 0xE3, 0x6C, 0x9D, 0xA7 },
797 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
798 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
799 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
800 0x52, 0x52, 0x25, 0x25 },
801 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
802 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
803 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100804 0x4E, 0xE7, 0xAD, 0x67 }
805};
806#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000807
Valerio Settia3f99592022-12-14 10:56:54 +0100808/*
809 * SHA-256 test vectors
810 */
811#if defined(MBEDTLS_SHA256_C)
812static sha_test_sum_t sha256_test_sum[] =
813{
Paul Bakker5121ce52009-01-03 21:22:43 +0000814 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
815 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
816 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
817 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
818 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
819 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
820 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
821 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
822 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
823 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
824 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
825 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
826};
Valerio Settia3f99592022-12-14 10:56:54 +0100827#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000828
829/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000830 * Checkup routine
831 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100832static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000833{
Valerio Settia3f99592022-12-14 10:56:54 +0100834 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500835 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200836 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
Valerio Settia3f99592022-12-14 10:56:54 +0100839#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100841#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100843#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100845#endif
846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 buf = mbedtls_calloc(1024, sizeof(unsigned char));
848 if (NULL == buf) {
849 if (verbose != 0) {
850 mbedtls_printf("Buffer allocation failed\n");
851 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500854 }
855
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200857
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 for (i = 0; i < 3; i++) {
859 if (verbose != 0) {
860 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
861 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100864 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000866
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 if (i == 2) {
868 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 for (int j = 0; j < 1000; j++) {
871 ret = mbedtls_sha256_update(&ctx, buf, buflen);
872 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100873 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100875 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 } else {
878 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
879 sha_test_buflen[i]);
880 if (ret != 0) {
881 goto fail;
882 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100883 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000884
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100886 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100888
Paul Bakker5121ce52009-01-03 21:22:43 +0000889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100891 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100892 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100893 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000894
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 if (verbose != 0) {
896 mbedtls_printf("passed\n");
897 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000898 }
899
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 if (verbose != 0) {
901 mbedtls_printf("\n");
902 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000903
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100904 goto exit;
905
906fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 if (verbose != 0) {
908 mbedtls_printf("failed\n");
909 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100910
Paul Bakker5b4af392014-06-26 12:09:34 +0200911exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 mbedtls_sha256_free(&ctx);
913 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200914
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000916}
917
Valerio Settia3f99592022-12-14 10:56:54 +0100918#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100919int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100920{
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100922}
923#endif /* MBEDTLS_SHA256_C */
924
925#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100926int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100927{
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100929}
930#endif /* MBEDTLS_SHA224_C */
931
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000933
Valerio Settia3f99592022-12-14 10:56:54 +0100934#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */