blob: 49a233d63f381045f405b930d7a9c009bea5f67e [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
60# pragma GCC target ("arch=armv8-a+crypto")
61# endif
62# else
63# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
64# endif
Jerry Yu35f2b262023-02-15 11:35:55 +080065# endif
66/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000067# include <arm_neon.h>
68# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000069# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
70# if defined(__unix__)
71# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010072/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000073# include <sys/auxv.h>
74# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010075/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000076# include <signal.h>
77# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000078# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000079#elif defined(_M_ARM64)
80# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010081 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000082# include <arm64_neon.h>
83# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000084#else
85# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
86# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
87#endif
88
89#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
90/*
91 * Capability detection code comes early, so we can disable
92 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
93 */
94#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +010095static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000096{
Gilles Peskine449bd832023-01-11 14:50:10 +010097 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000098}
99#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +0100100static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000101{
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000103}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000104#elif defined(_M_ARM64)
105#define WIN32_LEAN_AND_MEAN
106#include <Windows.h>
107#include <processthreadsapi.h>
108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000110{
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
112 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +0000113}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000114#elif defined(__unix__) && defined(SIG_SETMASK)
115/* Detection with SIGILL, setjmp() and longjmp() */
116#include <signal.h>
117#include <setjmp.h>
118
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000119static jmp_buf return_from_sigill;
120
121/*
122 * A64 SHA256 support detection via SIGILL
123 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100124static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000125{
126 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000128}
129
Gilles Peskine449bd832023-01-11 14:50:10 +0100130static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000131{
132 struct sigaction old_action, new_action;
133
134 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 if (sigprocmask(0, NULL, &old_mask)) {
136 return 0;
137 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000138
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000140 new_action.sa_flags = 0;
141 new_action.sa_handler = sigill_handler;
142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000144
145 static int ret = 0;
146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000148 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000150 ret = 1;
151 }
152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 sigaction(SIGILL, &old_action, NULL);
154 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000155
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000157}
158#else
159#warning "No mechanism to detect A64_CRYPTO found, using C code only"
160#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
161#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
162
163#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
164
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200165#if !defined(MBEDTLS_SHA256_ALT)
166
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000167#define SHA256_BLOCK_SIZE 64
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200170{
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200172}
173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200175{
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200177 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200181}
182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
184 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200185{
186 *dst = *src;
187}
188
Paul Bakker5121ce52009-01-03 21:22:43 +0000189/*
190 * SHA-256 context setup
191 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100192int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000193{
Valerio Settia3f99592022-12-14 10:56:54 +0100194#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100196 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 }
Valerio Settia3f99592022-12-14 10:56:54 +0100198#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100200 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 }
Valerio Settia3f99592022-12-14 10:56:54 +0100202#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100204 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200206#endif
207
Paul Bakker5121ce52009-01-03 21:22:43 +0000208 ctx->total[0] = 0;
209 ctx->total[1] = 0;
210
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100212#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000213 ctx->state[0] = 0x6A09E667;
214 ctx->state[1] = 0xBB67AE85;
215 ctx->state[2] = 0x3C6EF372;
216 ctx->state[3] = 0xA54FF53A;
217 ctx->state[4] = 0x510E527F;
218 ctx->state[5] = 0x9B05688C;
219 ctx->state[6] = 0x1F83D9AB;
220 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100221#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200223#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000224 ctx->state[0] = 0xC1059ED8;
225 ctx->state[1] = 0x367CD507;
226 ctx->state[2] = 0x3070DD17;
227 ctx->state[3] = 0xF70E5939;
228 ctx->state[4] = 0xFFC00B31;
229 ctx->state[5] = 0x68581511;
230 ctx->state[6] = 0x64F98FA7;
231 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200232#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 }
234
Valerio Settia3f99592022-12-14 10:56:54 +0100235#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000236 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100237#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000240}
241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200243static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000244{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200245 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
246 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
247 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
248 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
249 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
250 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
251 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
252 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
253 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
254 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
255 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
256 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
257 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
258 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
259 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
260 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
261};
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000263#endif
264
265#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
266 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
267
268#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
269# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
270# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
271#endif
272
273static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000275{
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
277 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000278
279 size_t processed = 0;
280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000282 len >= SHA256_BLOCK_SIZE;
283 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 msg += SHA256_BLOCK_SIZE,
285 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000286 uint32x4_t tmp, abcd_prev;
287
288 uint32x4_t abcd_orig = abcd;
289 uint32x4_t efgh_orig = efgh;
290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
292 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
293 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
294 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000295
296#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
297 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
299 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
300 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
301 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000302#endif
303
304 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000306 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
308 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000309
310 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000312 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
314 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000315
316 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000318 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
320 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000321
322 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000324 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
326 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000327
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000329 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
331 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
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 t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
338 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000339 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
341 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000342
343 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
345 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
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 + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
352 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
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
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 abcd = vaddq_u32(abcd, abcd_orig);
359 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000360 }
361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 vst1q_u32(&ctx->state[0], abcd);
363 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000364
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000366}
367
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100368#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
369/*
370 * This function is for internal use only if we are building both C and A64
371 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
372 */
373static
374#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100375int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
376 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000377{
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
379 SHA256_BLOCK_SIZE) ==
380 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000381}
382
Jerry Yu92fc5382023-02-16 11:17:11 +0800383#if defined(MBEDTLS_POP_TARGET_PRAGMA)
384#pragma clang attribute pop
385#undef MBEDTLS_POP_TARGET_PRAGMA
386#endif
387
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000388#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
389
390
391#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
392#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
393#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
394#endif
395
396
397#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
398 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
401#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
404#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
407#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
410#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200412#define R(t) \
413 ( \
414 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
415 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100416 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200419 do \
420 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
422 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200423 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100426#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
427/*
428 * This function is for internal use only if we are building both C and A64
429 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
430 */
431static
432#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100433int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
434 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200435{
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200437 uint32_t temp1, temp2, W[64];
438 uint32_t A[8];
439 } local;
440
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200441 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200444 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200446
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200447#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 for (i = 0; i < 64; i++) {
449 if (i < 16) {
450 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
451 } else {
452 R(i);
453 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
456 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200457
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200458 local.temp1 = local.A[7]; local.A[7] = local.A[6];
459 local.A[6] = local.A[5]; local.A[5] = local.A[4];
460 local.A[4] = local.A[3]; local.A[3] = local.A[2];
461 local.A[2] = local.A[1]; local.A[1] = local.A[0];
462 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200463 }
464#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 for (i = 0; i < 16; i++) {
466 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200467 }
468
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 for (i = 0; i < 16; i += 8) {
470 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
471 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
472 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
473 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
474 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
475 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
476 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
477 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
478 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
479 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
480 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
481 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
482 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
483 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
484 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
485 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
486 }
487
488 for (i = 16; i < 64; i += 8) {
489 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
490 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
491 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
492 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
493 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
494 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
495 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
496 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
497 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
498 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
499 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
500 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
501 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
502 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
503 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
504 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200505 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200506#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200507
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200509 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100511
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200512 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100514
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000516}
Jaeden Amero041039f2018-02-19 15:28:08 +0000517
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000518#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
519
520
521#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
522
523static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000525{
526 size_t processed = 0;
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 while (len >= SHA256_BLOCK_SIZE) {
529 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
530 return 0;
531 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000532
533 data += SHA256_BLOCK_SIZE;
534 len -= SHA256_BLOCK_SIZE;
535
536 processed += SHA256_BLOCK_SIZE;
537 }
538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000540}
541
542#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
543
544
545#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000548{
549 static int done = 0;
550 static int supported = 0;
551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000553 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000554 done = 1;
555 }
556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000558}
559
Gilles Peskine449bd832023-01-11 14:50:10 +0100560static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
561 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000562{
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 if (mbedtls_a64_crypto_sha256_has_support()) {
564 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
565 } else {
566 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
567 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000568}
569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
571 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000572{
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 if (mbedtls_a64_crypto_sha256_has_support()) {
574 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
575 } else {
576 return mbedtls_internal_sha256_process_c(ctx, data);
577 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000578}
579
580#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
581
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
583/*
584 * SHA-256 process buffer
585 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100586int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
587 const unsigned char *input,
588 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000589{
Janos Follath24eed8d2019-11-22 13:21:35 +0000590 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000591 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000592 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 if (ilen == 0) {
595 return 0;
596 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000599 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Paul Bakker5c2364c2012-10-01 14:41:15 +0000601 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 ctx->total[0] &= 0xFFFFFFFF;
603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000605 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 if (left && ilen >= fill) {
609 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
612 return ret;
613 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100614
Paul Bakker5121ce52009-01-03 21:22:43 +0000615 input += fill;
616 ilen -= fill;
617 left = 0;
618 }
619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000621 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 mbedtls_internal_sha256_process_many(ctx, input, ilen);
623 if (processed < SHA256_BLOCK_SIZE) {
624 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
625 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100626
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000627 input += processed;
628 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 }
630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 if (ilen > 0) {
632 memcpy((void *) (ctx->buffer + left), input, ilen);
633 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000636}
637
Paul Bakker5121ce52009-01-03 21:22:43 +0000638/*
639 * SHA-256 final digest
640 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100641int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
642 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000643{
Janos Follath24eed8d2019-11-22 13:21:35 +0000644 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200645 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000646 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000647
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200648 /*
649 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
650 */
651 used = ctx->total[0] & 0x3F;
652
653 ctx->buffer[used++] = 0x80;
654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200656 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 memset(ctx->buffer + used, 0, 56 - used);
658 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200659 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
663 return ret;
664 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200667 }
668
669 /*
670 * Add message length
671 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 high = (ctx->total[0] >> 29)
673 | (ctx->total[1] << 3);
674 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
677 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
680 return ret;
681 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100682
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200683 /*
684 * Output final state
685 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
687 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
688 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
689 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
690 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
691 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
692 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
David Horstmann687262c2022-10-06 17:54:57 +0100694 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200695#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100696 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200697#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 if (!truncated) {
699 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
700 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100701
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000703}
704
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200706
Paul Bakker5121ce52009-01-03 21:22:43 +0000707/*
708 * output = SHA-256( input buffer )
709 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100710int mbedtls_sha256(const unsigned char *input,
711 size_t ilen,
712 unsigned char *output,
713 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000714{
Janos Follath24eed8d2019-11-22 13:21:35 +0000715 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
Valerio Settia3f99592022-12-14 10:56:54 +0100718#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100720 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 }
Valerio Settia3f99592022-12-14 10:56:54 +0100722#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100724 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 }
Valerio Settia3f99592022-12-14 10:56:54 +0100726#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100728 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200730#endif
731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100735 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100739 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100743 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100745
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100746exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000750}
751
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200752#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000753/*
754 * FIPS-180-2 test vectors
755 */
Valerio Settia3f99592022-12-14 10:56:54 +0100756static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000757{
758 { "abc" },
759 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
760 { "" }
761};
762
Valerio Settia3f99592022-12-14 10:56:54 +0100763static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000764{
765 3, 56, 1000
766};
767
Valerio Settia3f99592022-12-14 10:56:54 +0100768typedef const unsigned char (sha_test_sum_t)[32];
769
770/*
771 * SHA-224 test vectors
772 */
773#if defined(MBEDTLS_SHA224_C)
774static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000775{
Paul Bakker5121ce52009-01-03 21:22:43 +0000776 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
777 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
778 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
779 0xE3, 0x6C, 0x9D, 0xA7 },
780 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
781 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
782 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
783 0x52, 0x52, 0x25, 0x25 },
784 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
785 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
786 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100787 0x4E, 0xE7, 0xAD, 0x67 }
788};
789#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000790
Valerio Settia3f99592022-12-14 10:56:54 +0100791/*
792 * SHA-256 test vectors
793 */
794#if defined(MBEDTLS_SHA256_C)
795static sha_test_sum_t sha256_test_sum[] =
796{
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
798 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
799 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
800 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
801 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
802 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
803 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
804 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
805 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
806 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
807 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
808 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
809};
Valerio Settia3f99592022-12-14 10:56:54 +0100810#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000811
812/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000813 * Checkup routine
814 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100815static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000816{
Valerio Settia3f99592022-12-14 10:56:54 +0100817 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500818 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200819 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000821
Valerio Settia3f99592022-12-14 10:56:54 +0100822#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100824#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100826#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100828#endif
829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 buf = mbedtls_calloc(1024, sizeof(unsigned char));
831 if (NULL == buf) {
832 if (verbose != 0) {
833 mbedtls_printf("Buffer allocation failed\n");
834 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500837 }
838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 for (i = 0; i < 3; i++) {
842 if (verbose != 0) {
843 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
844 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100847 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 if (i == 2) {
851 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 for (int j = 0; j < 1000; j++) {
854 ret = mbedtls_sha256_update(&ctx, buf, buflen);
855 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100856 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100858 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100859
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 } else {
861 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
862 sha_test_buflen[i]);
863 if (ret != 0) {
864 goto fail;
865 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100866 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100869 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100871
Paul Bakker5121ce52009-01-03 21:22:43 +0000872
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100874 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100875 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100876 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 if (verbose != 0) {
879 mbedtls_printf("passed\n");
880 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000881 }
882
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 if (verbose != 0) {
884 mbedtls_printf("\n");
885 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100887 goto exit;
888
889fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 if (verbose != 0) {
891 mbedtls_printf("failed\n");
892 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100893
Paul Bakker5b4af392014-06-26 12:09:34 +0200894exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 mbedtls_sha256_free(&ctx);
896 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000899}
900
Valerio Settia3f99592022-12-14 10:56:54 +0100901#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100902int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100903{
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100905}
906#endif /* MBEDTLS_SHA256_C */
907
908#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100909int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100910{
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100912}
913#endif /* MBEDTLS_SHA224_C */
914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000916
Valerio Settia3f99592022-12-14 10:56:54 +0100917#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */