blob: 010f4bc02fc6ec8d79582a367331f404fd454b15 [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)
42# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
43# endif
44/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000045# include <arm_neon.h>
46# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000047# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
48# if defined(__unix__)
49# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010050/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000051# include <sys/auxv.h>
52# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010053/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000054# include <signal.h>
55# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000056# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000057#elif defined(_M_ARM64)
58# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010059 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000060# include <arm64_neon.h>
61# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000062#else
63# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
64# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
65#endif
66
67#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
68/*
69 * Capability detection code comes early, so we can disable
70 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
71 */
72#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +010073static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000074{
Gilles Peskine449bd832023-01-11 14:50:10 +010075 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000076}
77#elif defined(__APPLE__)
Gilles Peskine449bd832023-01-11 14:50:10 +010078static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000079{
Gilles Peskine449bd832023-01-11 14:50:10 +010080 return 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000081}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000082#elif defined(_M_ARM64)
83#define WIN32_LEAN_AND_MEAN
84#include <Windows.h>
85#include <processthreadsapi.h>
86
Gilles Peskine449bd832023-01-11 14:50:10 +010087static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000088{
Gilles Peskine449bd832023-01-11 14:50:10 +010089 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
90 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000091}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000092#elif defined(__unix__) && defined(SIG_SETMASK)
93/* Detection with SIGILL, setjmp() and longjmp() */
94#include <signal.h>
95#include <setjmp.h>
96
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000097static jmp_buf return_from_sigill;
98
99/*
100 * A64 SHA256 support detection via SIGILL
101 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100102static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000103{
104 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100105 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000106}
107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000109{
110 struct sigaction old_action, new_action;
111
112 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100113 if (sigprocmask(0, NULL, &old_mask)) {
114 return 0;
115 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000116
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000118 new_action.sa_flags = 0;
119 new_action.sa_handler = sigill_handler;
120
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000122
123 static int ret = 0;
124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000126 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000128 ret = 1;
129 }
130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 sigaction(SIGILL, &old_action, NULL);
132 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000135}
136#else
137#warning "No mechanism to detect A64_CRYPTO found, using C code only"
138#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
139#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
140
141#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
142
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200143#if !defined(MBEDTLS_SHA256_ALT)
144
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000145#define SHA256_BLOCK_SIZE 64
146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200148{
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200150}
151
Gilles Peskine449bd832023-01-11 14:50:10 +0100152void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200153{
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200155 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200159}
160
Gilles Peskine449bd832023-01-11 14:50:10 +0100161void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
162 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200163{
164 *dst = *src;
165}
166
Paul Bakker5121ce52009-01-03 21:22:43 +0000167/*
168 * SHA-256 context setup
169 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100170int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000171{
Valerio Settia3f99592022-12-14 10:56:54 +0100172#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100174 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 }
Valerio Settia3f99592022-12-14 10:56:54 +0100176#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100178 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 }
Valerio Settia3f99592022-12-14 10:56:54 +0100180#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100182 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200184#endif
185
Paul Bakker5121ce52009-01-03 21:22:43 +0000186 ctx->total[0] = 0;
187 ctx->total[1] = 0;
188
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100190#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000191 ctx->state[0] = 0x6A09E667;
192 ctx->state[1] = 0xBB67AE85;
193 ctx->state[2] = 0x3C6EF372;
194 ctx->state[3] = 0xA54FF53A;
195 ctx->state[4] = 0x510E527F;
196 ctx->state[5] = 0x9B05688C;
197 ctx->state[6] = 0x1F83D9AB;
198 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100199#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200201#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000202 ctx->state[0] = 0xC1059ED8;
203 ctx->state[1] = 0x367CD507;
204 ctx->state[2] = 0x3070DD17;
205 ctx->state[3] = 0xF70E5939;
206 ctx->state[4] = 0xFFC00B31;
207 ctx->state[5] = 0x68581511;
208 ctx->state[6] = 0x64F98FA7;
209 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200210#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 }
212
Valerio Settia3f99592022-12-14 10:56:54 +0100213#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000214 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100215#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000218}
219
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200221static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000222{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200223 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
224 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
225 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
226 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
227 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
228 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
229 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
230 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
231 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
232 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
233 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
234 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
235 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
236 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
237 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
238 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
239};
Paul Bakker5121ce52009-01-03 21:22:43 +0000240
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000241#endif
242
243#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
244 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
245
246#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
247# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
248# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
249#endif
250
251static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000253{
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
255 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000256
257 size_t processed = 0;
258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000260 len >= SHA256_BLOCK_SIZE;
261 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 msg += SHA256_BLOCK_SIZE,
263 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000264 uint32x4_t tmp, abcd_prev;
265
266 uint32x4_t abcd_orig = abcd;
267 uint32x4_t efgh_orig = efgh;
268
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
270 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
271 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
272 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000273
274#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
275 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
277 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
278 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
279 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000280#endif
281
282 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000284 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
286 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000287
288 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000290 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
292 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000293
294 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000296 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
298 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000299
300 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000302 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
304 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000307 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
309 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000310 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
312 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000313
314 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
316 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000317 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
319 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000320
321 /* Rounds t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
323 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
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
328 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
330 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000331 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
333 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000334 }
335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 abcd = vaddq_u32(abcd, abcd_orig);
337 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000338 }
339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 vst1q_u32(&ctx->state[0], abcd);
341 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000344}
345
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100346#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
347/*
348 * This function is for internal use only if we are building both C and A64
349 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
350 */
351static
352#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100353int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
354 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000355{
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
357 SHA256_BLOCK_SIZE) ==
358 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000359}
360
361#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
362
363
364#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
365#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
366#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
367#endif
368
369
370#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
371 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
374#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Gilles Peskine449bd832023-01-11 14:50:10 +0100376#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
377#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
Gilles Peskine449bd832023-01-11 14:50:10 +0100379#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
380#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
383#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200385#define R(t) \
386 ( \
387 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
388 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100389 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200392 do \
393 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
395 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200396 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100399#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
400/*
401 * This function is for internal use only if we are building both C and A64
402 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
403 */
404static
405#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100406int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
407 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200408{
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200410 uint32_t temp1, temp2, W[64];
411 uint32_t A[8];
412 } local;
413
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200414 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200417 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200419
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200420#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 for (i = 0; i < 64; i++) {
422 if (i < 16) {
423 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
424 } else {
425 R(i);
426 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200427
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
429 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200430
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200431 local.temp1 = local.A[7]; local.A[7] = local.A[6];
432 local.A[6] = local.A[5]; local.A[5] = local.A[4];
433 local.A[4] = local.A[3]; local.A[3] = local.A[2];
434 local.A[2] = local.A[1]; local.A[1] = local.A[0];
435 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200436 }
437#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 for (i = 0; i < 16; i++) {
439 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200440 }
441
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 for (i = 0; i < 16; i += 8) {
443 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
444 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
445 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
446 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
447 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
448 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
449 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
450 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
451 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
452 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
453 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
454 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
455 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
456 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
457 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
458 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
459 }
460
461 for (i = 16; i < 64; i += 8) {
462 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
463 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
464 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
465 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
466 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
467 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
468 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
469 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
470 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
471 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
472 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
473 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
474 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
475 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
476 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
477 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200478 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200479#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200482 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100484
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200485 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100487
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000489}
Jaeden Amero041039f2018-02-19 15:28:08 +0000490
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000491#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
492
493
494#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
495
496static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000498{
499 size_t processed = 0;
500
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 while (len >= SHA256_BLOCK_SIZE) {
502 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
503 return 0;
504 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000505
506 data += SHA256_BLOCK_SIZE;
507 len -= SHA256_BLOCK_SIZE;
508
509 processed += SHA256_BLOCK_SIZE;
510 }
511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000513}
514
515#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
516
517
518#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
519
Gilles Peskine449bd832023-01-11 14:50:10 +0100520static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000521{
522 static int done = 0;
523 static int supported = 0;
524
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000526 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000527 done = 1;
528 }
529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000531}
532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
534 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000535{
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 if (mbedtls_a64_crypto_sha256_has_support()) {
537 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
538 } else {
539 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
540 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000541}
542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
544 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000545{
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 if (mbedtls_a64_crypto_sha256_has_support()) {
547 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
548 } else {
549 return mbedtls_internal_sha256_process_c(ctx, data);
550 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000551}
552
553#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
554
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556/*
557 * SHA-256 process buffer
558 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100559int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
560 const unsigned char *input,
561 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000562{
Janos Follath24eed8d2019-11-22 13:21:35 +0000563 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000564 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000565 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 if (ilen == 0) {
568 return 0;
569 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
571 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000572 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
Paul Bakker5c2364c2012-10-01 14:41:15 +0000574 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000575 ctx->total[0] &= 0xFFFFFFFF;
576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000578 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 if (left && ilen >= fill) {
582 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
585 return ret;
586 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100587
Paul Bakker5121ce52009-01-03 21:22:43 +0000588 input += fill;
589 ilen -= fill;
590 left = 0;
591 }
592
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000594 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 mbedtls_internal_sha256_process_many(ctx, input, ilen);
596 if (processed < SHA256_BLOCK_SIZE) {
597 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
598 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100599
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000600 input += processed;
601 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 }
603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 if (ilen > 0) {
605 memcpy((void *) (ctx->buffer + left), input, ilen);
606 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000609}
610
Paul Bakker5121ce52009-01-03 21:22:43 +0000611/*
612 * SHA-256 final digest
613 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100614int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
615 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000616{
Janos Follath24eed8d2019-11-22 13:21:35 +0000617 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200618 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000619 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200621 /*
622 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
623 */
624 used = ctx->total[0] & 0x3F;
625
626 ctx->buffer[used++] = 0x80;
627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200629 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 memset(ctx->buffer + used, 0, 56 - used);
631 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200632 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
636 return ret;
637 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200640 }
641
642 /*
643 * Add message length
644 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 high = (ctx->total[0] >> 29)
646 | (ctx->total[1] << 3);
647 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
650 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
653 return ret;
654 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100655
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200656 /*
657 * Output final state
658 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
660 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
661 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
662 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
663 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
664 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
665 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
David Horstmann687262c2022-10-06 17:54:57 +0100667 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200668#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100669 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200670#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 if (!truncated) {
672 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
673 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000676}
677
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200678#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200679
Paul Bakker5121ce52009-01-03 21:22:43 +0000680/*
681 * output = SHA-256( input buffer )
682 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100683int mbedtls_sha256(const unsigned char *input,
684 size_t ilen,
685 unsigned char *output,
686 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000687{
Janos Follath24eed8d2019-11-22 13:21:35 +0000688 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000690
Valerio Settia3f99592022-12-14 10:56:54 +0100691#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100693 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 }
Valerio Settia3f99592022-12-14 10:56:54 +0100695#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100697 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 }
Valerio Settia3f99592022-12-14 10:56:54 +0100699#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100701 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200703#endif
704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100708 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100712 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100716 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100718
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100719exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000723}
724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000726/*
727 * FIPS-180-2 test vectors
728 */
Valerio Settia3f99592022-12-14 10:56:54 +0100729static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000730{
731 { "abc" },
732 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
733 { "" }
734};
735
Valerio Settia3f99592022-12-14 10:56:54 +0100736static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000737{
738 3, 56, 1000
739};
740
Valerio Settia3f99592022-12-14 10:56:54 +0100741typedef const unsigned char (sha_test_sum_t)[32];
742
743/*
744 * SHA-224 test vectors
745 */
746#if defined(MBEDTLS_SHA224_C)
747static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000748{
Paul Bakker5121ce52009-01-03 21:22:43 +0000749 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
750 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
751 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
752 0xE3, 0x6C, 0x9D, 0xA7 },
753 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
754 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
755 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
756 0x52, 0x52, 0x25, 0x25 },
757 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
758 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
759 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100760 0x4E, 0xE7, 0xAD, 0x67 }
761};
762#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000763
Valerio Settia3f99592022-12-14 10:56:54 +0100764/*
765 * SHA-256 test vectors
766 */
767#if defined(MBEDTLS_SHA256_C)
768static sha_test_sum_t sha256_test_sum[] =
769{
Paul Bakker5121ce52009-01-03 21:22:43 +0000770 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
771 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
772 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
773 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
774 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
775 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
776 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
777 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
778 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
779 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
780 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
781 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
782};
Valerio Settia3f99592022-12-14 10:56:54 +0100783#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000784
785/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 * Checkup routine
787 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000789{
Valerio Settia3f99592022-12-14 10:56:54 +0100790 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500791 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200792 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000794
Valerio Settia3f99592022-12-14 10:56:54 +0100795#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100797#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100799#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100801#endif
802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 buf = mbedtls_calloc(1024, sizeof(unsigned char));
804 if (NULL == buf) {
805 if (verbose != 0) {
806 mbedtls_printf("Buffer allocation failed\n");
807 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500810 }
811
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 for (i = 0; i < 3; i++) {
815 if (verbose != 0) {
816 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
817 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000818
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100820 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 if (i == 2) {
824 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 for (int j = 0; j < 1000; j++) {
827 ret = mbedtls_sha256_update(&ctx, buf, buflen);
828 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100829 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100831 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100832
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 } else {
834 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
835 sha_test_buflen[i]);
836 if (ret != 0) {
837 goto fail;
838 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100839 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100842 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100844
Paul Bakker5121ce52009-01-03 21:22:43 +0000845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100847 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100848 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100849 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 if (verbose != 0) {
852 mbedtls_printf("passed\n");
853 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000854 }
855
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 if (verbose != 0) {
857 mbedtls_printf("\n");
858 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000859
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100860 goto exit;
861
862fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 if (verbose != 0) {
864 mbedtls_printf("failed\n");
865 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100866
Paul Bakker5b4af392014-06-26 12:09:34 +0200867exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 mbedtls_sha256_free(&ctx);
869 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200870
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000872}
873
Valerio Settia3f99592022-12-14 10:56:54 +0100874#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100875int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100876{
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100878}
879#endif /* MBEDTLS_SHA256_C */
880
881#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100882int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100883{
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100885}
886#endif /* MBEDTLS_SHA224_C */
887
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000889
Valerio Settia3f99592022-12-14 10:56:54 +0100890#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */