blob: 81c011b3389a2f7691d0742d4ff707cd36c413a8 [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__)
57# if __GNUC__ < 6 /* TODO: check sha256 compatible for GCC */
58# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
59# else
Jerry Yu2f2c0492023-02-16 14:24:46 +080060# pragma GCC push_options
Jerry Yu64e5d4a2023-02-15 11:46:57 +080061# pragma GCC target ("arch=armv8-a+crypto")
Jerry Yu2f2c0492023-02-16 14:24:46 +080062# define MBEDTLS_POP_TARGET_PRAGMA
Jerry Yu64e5d4a2023-02-15 11:46:57 +080063# endif
64# else
65# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
66# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080067# endif
68/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000069# include <arm_neon.h>
70# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000071# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
72# if defined(__unix__)
73# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010074/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000075# include <sys/auxv.h>
76# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010077/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000078# include <signal.h>
79# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000080# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000081#elif defined(_M_ARM64)
82# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010083 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000084# include <arm64_neon.h>
85# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000086#else
87# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
88# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
89#endif
90
91#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
92/*
93 * Capability detection code comes early, so we can disable
94 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
95 */
96#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +010097static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000098{
Gilles Peskine449bd832023-01-11 14:50:10 +010099 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000100}
101#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100102static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000103{
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000105}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000106#elif defined(_M_ARM64)
107#define WIN32_LEAN_AND_MEAN
108#include <Windows.h>
109#include <processthreadsapi.h>
110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000112{
Gilles Peskine449bd832023-01-11 14:50:10 +0100113 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
114 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000115}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000116#elif defined(__unix__) && defined(SIG_SETMASK)
117/* Detection with SIGILL, setjmp() and longjmp() */
118#include <signal.h>
119#include <setjmp.h>
120
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000121static jmp_buf return_from_sigill;
122
123/*
124 * A64 SHA256 support detection via SIGILL
125 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100126static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000127{
128 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000130}
131
Gilles Peskine449bd832023-01-11 14:50:10 +0100132static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000133{
134 struct sigaction old_action, new_action;
135
136 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 if (sigprocmask(0, NULL, &old_mask)) {
138 return 0;
139 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000142 new_action.sa_flags = 0;
143 new_action.sa_handler = sigill_handler;
144
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000146
147 static int ret = 0;
148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000150 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000152 ret = 1;
153 }
154
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 sigaction(SIGILL, &old_action, NULL);
156 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000159}
160#else
161#warning "No mechanism to detect A64_CRYPTO found, using C code only"
162#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
163#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
164
165#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
166
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200167#if !defined(MBEDTLS_SHA256_ALT)
168
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000169#define SHA256_BLOCK_SIZE 64
170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200172{
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200174}
175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200177{
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200179 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200183}
184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
186 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200187{
188 *dst = *src;
189}
190
Paul Bakker5121ce52009-01-03 21:22:43 +0000191/*
192 * SHA-256 context setup
193 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100194int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000195{
Valerio Settia3f99592022-12-14 10:56:54 +0100196#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100198 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 }
Valerio Settia3f99592022-12-14 10:56:54 +0100200#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100202 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 }
Valerio Settia3f99592022-12-14 10:56:54 +0100204#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100206 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200208#endif
209
Paul Bakker5121ce52009-01-03 21:22:43 +0000210 ctx->total[0] = 0;
211 ctx->total[1] = 0;
212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100214#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 ctx->state[0] = 0x6A09E667;
216 ctx->state[1] = 0xBB67AE85;
217 ctx->state[2] = 0x3C6EF372;
218 ctx->state[3] = 0xA54FF53A;
219 ctx->state[4] = 0x510E527F;
220 ctx->state[5] = 0x9B05688C;
221 ctx->state[6] = 0x1F83D9AB;
222 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100223#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200225#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000226 ctx->state[0] = 0xC1059ED8;
227 ctx->state[1] = 0x367CD507;
228 ctx->state[2] = 0x3070DD17;
229 ctx->state[3] = 0xF70E5939;
230 ctx->state[4] = 0xFFC00B31;
231 ctx->state[5] = 0x68581511;
232 ctx->state[6] = 0x64F98FA7;
233 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200234#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000235 }
236
Valerio Settia3f99592022-12-14 10:56:54 +0100237#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000238 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100239#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100240
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000242}
243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200245static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000246{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200247 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
248 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
249 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
250 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
251 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
252 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
253 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
254 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
255 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
256 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
257 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
258 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
259 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
260 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
261 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
262 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
263};
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000265#endif
266
267#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
268 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
269
270#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
271# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
272# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
273#endif
274
275static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000277{
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
279 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000280
281 size_t processed = 0;
282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000284 len >= SHA256_BLOCK_SIZE;
285 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 msg += SHA256_BLOCK_SIZE,
287 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000288 uint32x4_t tmp, abcd_prev;
289
290 uint32x4_t abcd_orig = abcd;
291 uint32x4_t efgh_orig = efgh;
292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
294 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
295 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
296 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000297
298#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
299 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
301 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
302 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
303 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000304#endif
305
306 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000308 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
310 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000311
312 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000314 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
316 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000317
318 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
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 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
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
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000331 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
333 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
336 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000337
338 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
340 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000341 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
343 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000344
345 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
347 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000348 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
350 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000351
352 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
354 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000355 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
357 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000358 }
359
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 abcd = vaddq_u32(abcd, abcd_orig);
361 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000362 }
363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 vst1q_u32(&ctx->state[0], abcd);
365 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000368}
369
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100370#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
371/*
372 * This function is for internal use only if we are building both C and A64
373 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
374 */
375static
376#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100377int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
378 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000379{
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
381 SHA256_BLOCK_SIZE) ==
382 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000383}
384
Jerry Yu92fc5382023-02-16 11:17:11 +0800385#if defined(MBEDTLS_POP_TARGET_PRAGMA)
Jerry Yu2f2c0492023-02-16 14:24:46 +0800386#if defined(__clang__)
Jerry Yu92fc5382023-02-16 11:17:11 +0800387#pragma clang attribute pop
Jerry Yu2f2c0492023-02-16 14:24:46 +0800388#elif defined(__GNUC__)
389#pragma GCC pop_options
390#endif
Jerry Yu92fc5382023-02-16 11:17:11 +0800391#undef MBEDTLS_POP_TARGET_PRAGMA
392#endif
393
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000394#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
395
396
397#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
398#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
399#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
400#endif
401
402
403#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
404 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
407#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
410#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
413#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
416#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200418#define R(t) \
419 ( \
420 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
421 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100422 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
Gilles Peskine449bd832023-01-11 14:50:10 +0100424#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200425 do \
426 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
428 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200429 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100432#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
433/*
434 * This function is for internal use only if we are building both C and A64
435 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
436 */
437static
438#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100439int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
440 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200441{
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200443 uint32_t temp1, temp2, W[64];
444 uint32_t A[8];
445 } local;
446
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200447 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200450 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200452
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200453#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 for (i = 0; i < 64; i++) {
455 if (i < 16) {
456 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
457 } else {
458 R(i);
459 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200460
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
462 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200463
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200464 local.temp1 = local.A[7]; local.A[7] = local.A[6];
465 local.A[6] = local.A[5]; local.A[5] = local.A[4];
466 local.A[4] = local.A[3]; local.A[3] = local.A[2];
467 local.A[2] = local.A[1]; local.A[1] = local.A[0];
468 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200469 }
470#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 for (i = 0; i < 16; i++) {
472 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200473 }
474
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 for (i = 0; i < 16; i += 8) {
476 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
477 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
478 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
479 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
480 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
481 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
482 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
483 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
484 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
485 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
486 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
487 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
488 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
489 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
490 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
491 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
492 }
493
494 for (i = 16; i < 64; i += 8) {
495 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
496 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
497 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
498 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
499 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
500 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
501 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
502 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
503 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
504 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
505 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
506 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
507 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
508 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
509 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
510 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200511 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200512#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200513
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200515 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100517
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200518 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100520
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000522}
Jaeden Amero041039f2018-02-19 15:28:08 +0000523
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000524#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
525
526
527#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
528
529static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000531{
532 size_t processed = 0;
533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 while (len >= SHA256_BLOCK_SIZE) {
535 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
536 return 0;
537 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000538
539 data += SHA256_BLOCK_SIZE;
540 len -= SHA256_BLOCK_SIZE;
541
542 processed += SHA256_BLOCK_SIZE;
543 }
544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000546}
547
548#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
549
550
551#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000554{
555 static int done = 0;
556 static int supported = 0;
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000559 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000560 done = 1;
561 }
562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000564}
565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
567 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000568{
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 if (mbedtls_a64_crypto_sha256_has_support()) {
570 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
571 } else {
572 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
573 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000574}
575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
577 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000578{
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 if (mbedtls_a64_crypto_sha256_has_support()) {
580 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
581 } else {
582 return mbedtls_internal_sha256_process_c(ctx, data);
583 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000584}
585
586#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
587
Paul Bakker5121ce52009-01-03 21:22:43 +0000588
589/*
590 * SHA-256 process buffer
591 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100592int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
593 const unsigned char *input,
594 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000595{
Janos Follath24eed8d2019-11-22 13:21:35 +0000596 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000597 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000598 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 if (ilen == 0) {
601 return 0;
602 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
604 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000605 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
Paul Bakker5c2364c2012-10-01 14:41:15 +0000607 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 ctx->total[0] &= 0xFFFFFFFF;
609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000611 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 if (left && ilen >= fill) {
615 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
618 return ret;
619 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100620
Paul Bakker5121ce52009-01-03 21:22:43 +0000621 input += fill;
622 ilen -= fill;
623 left = 0;
624 }
625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000627 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 mbedtls_internal_sha256_process_many(ctx, input, ilen);
629 if (processed < SHA256_BLOCK_SIZE) {
630 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
631 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100632
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000633 input += processed;
634 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 }
636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 if (ilen > 0) {
638 memcpy((void *) (ctx->buffer + left), input, ilen);
639 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000642}
643
Paul Bakker5121ce52009-01-03 21:22:43 +0000644/*
645 * SHA-256 final digest
646 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100647int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
648 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000649{
Janos Follath24eed8d2019-11-22 13:21:35 +0000650 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200651 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000652 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000653
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200654 /*
655 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
656 */
657 used = ctx->total[0] & 0x3F;
658
659 ctx->buffer[used++] = 0x80;
660
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200662 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 memset(ctx->buffer + used, 0, 56 - used);
664 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200665 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200667
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
669 return ret;
670 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200673 }
674
675 /*
676 * Add message length
677 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 high = (ctx->total[0] >> 29)
679 | (ctx->total[1] << 3);
680 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
683 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
686 return ret;
687 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100688
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200689 /*
690 * Output final state
691 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
693 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
694 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
695 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
696 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
697 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
698 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000699
David Horstmann687262c2022-10-06 17:54:57 +0100700 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200701#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100702 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200703#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 if (!truncated) {
705 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
706 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100707
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000709}
710
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200712
Paul Bakker5121ce52009-01-03 21:22:43 +0000713/*
714 * output = SHA-256( input buffer )
715 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100716int mbedtls_sha256(const unsigned char *input,
717 size_t ilen,
718 unsigned char *output,
719 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000720{
Janos Follath24eed8d2019-11-22 13:21:35 +0000721 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000723
Valerio Settia3f99592022-12-14 10:56:54 +0100724#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100726 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 }
Valerio Settia3f99592022-12-14 10:56:54 +0100728#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100730 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 }
Valerio Settia3f99592022-12-14 10:56:54 +0100732#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100734 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200736#endif
737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100739
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100741 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100745 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100747
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100749 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100751
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100752exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100754
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000756}
757
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200758#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000759/*
760 * FIPS-180-2 test vectors
761 */
Valerio Settia3f99592022-12-14 10:56:54 +0100762static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000763{
764 { "abc" },
765 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
766 { "" }
767};
768
Valerio Settia3f99592022-12-14 10:56:54 +0100769static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000770{
771 3, 56, 1000
772};
773
Valerio Settia3f99592022-12-14 10:56:54 +0100774typedef const unsigned char (sha_test_sum_t)[32];
775
776/*
777 * SHA-224 test vectors
778 */
779#if defined(MBEDTLS_SHA224_C)
780static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000781{
Paul Bakker5121ce52009-01-03 21:22:43 +0000782 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
783 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
784 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
785 0xE3, 0x6C, 0x9D, 0xA7 },
786 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
787 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
788 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
789 0x52, 0x52, 0x25, 0x25 },
790 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
791 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
792 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100793 0x4E, 0xE7, 0xAD, 0x67 }
794};
795#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000796
Valerio Settia3f99592022-12-14 10:56:54 +0100797/*
798 * SHA-256 test vectors
799 */
800#if defined(MBEDTLS_SHA256_C)
801static sha_test_sum_t sha256_test_sum[] =
802{
Paul Bakker5121ce52009-01-03 21:22:43 +0000803 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
804 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
805 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
806 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
807 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
808 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
809 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
810 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
811 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
812 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
813 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
814 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
815};
Valerio Settia3f99592022-12-14 10:56:54 +0100816#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000817
818/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000819 * Checkup routine
820 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100821static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000822{
Valerio Settia3f99592022-12-14 10:56:54 +0100823 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500824 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200825 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000827
Valerio Settia3f99592022-12-14 10:56:54 +0100828#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100830#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100832#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100834#endif
835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 buf = mbedtls_calloc(1024, sizeof(unsigned char));
837 if (NULL == buf) {
838 if (verbose != 0) {
839 mbedtls_printf("Buffer allocation failed\n");
840 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500843 }
844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 for (i = 0; i < 3; i++) {
848 if (verbose != 0) {
849 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
850 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000851
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100853 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000855
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 if (i == 2) {
857 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 for (int j = 0; j < 1000; j++) {
860 ret = mbedtls_sha256_update(&ctx, buf, buflen);
861 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100862 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100864 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 } else {
867 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
868 sha_test_buflen[i]);
869 if (ret != 0) {
870 goto fail;
871 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100872 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000873
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100875 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100877
Paul Bakker5121ce52009-01-03 21:22:43 +0000878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100880 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100881 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100882 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if (verbose != 0) {
885 mbedtls_printf("passed\n");
886 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000887 }
888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 if (verbose != 0) {
890 mbedtls_printf("\n");
891 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100893 goto exit;
894
895fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 if (verbose != 0) {
897 mbedtls_printf("failed\n");
898 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100899
Paul Bakker5b4af392014-06-26 12:09:34 +0200900exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 mbedtls_sha256_free(&ctx);
902 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000905}
906
Valerio Settia3f99592022-12-14 10:56:54 +0100907#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100908int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100909{
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100911}
912#endif /* MBEDTLS_SHA256_C */
913
914#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100915int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100916{
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100918}
919#endif /* MBEDTLS_SHA224_C */
920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000922
Valerio Settia3f99592022-12-14 10:56:54 +0100923#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */