blob: cb09a71ec18d038acdafdfc598c5e10ba47a57b3 [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)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000040# include <arm_neon.h>
41# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000042# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
43# if defined(__unix__)
44# if defined(__linux__)
Gilles Peskine449bd832023-01-11 14:50:10 +010045/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000046# include <sys/auxv.h>
47# endif
Gilles Peskine449bd832023-01-11 14:50:10 +010048/* Use SIGILL on Unix, and fall back to it on Linux */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000049# include <signal.h>
50# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000051# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000052#elif defined(_M_ARM64)
53# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
Gilles Peskine449bd832023-01-11 14:50:10 +010054 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000055# include <arm64_neon.h>
56# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000057#else
58# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
59# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
60#endif
61
62#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
63/*
64 * Capability detection code comes early, so we can disable
65 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
66 */
67#if defined(HWCAP_SHA2)
Gilles Peskine449bd832023-01-11 14:50:10 +010068static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000069{
Gilles Peskine449bd832023-01-11 14:50:10 +010070 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000071}
72#elif defined(__APPLE__)
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 1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000076}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000077#elif defined(_M_ARM64)
78#define WIN32_LEAN_AND_MEAN
79#include <Windows.h>
80#include <processthreadsapi.h>
81
Gilles Peskine449bd832023-01-11 14:50:10 +010082static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000083{
Gilles Peskine449bd832023-01-11 14:50:10 +010084 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
85 1 : 0;
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000086}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000087#elif defined(__unix__) && defined(SIG_SETMASK)
88/* Detection with SIGILL, setjmp() and longjmp() */
89#include <signal.h>
90#include <setjmp.h>
91
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000092static jmp_buf return_from_sigill;
93
94/*
95 * A64 SHA256 support detection via SIGILL
96 */
Gilles Peskine449bd832023-01-11 14:50:10 +010097static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000098{
99 (void) signal;
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000101}
102
Gilles Peskine449bd832023-01-11 14:50:10 +0100103static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000104{
105 struct sigaction old_action, new_action;
106
107 sigset_t old_mask;
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 if (sigprocmask(0, NULL, &old_mask)) {
109 return 0;
110 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000111
Gilles Peskine449bd832023-01-11 14:50:10 +0100112 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000113 new_action.sa_flags = 0;
114 new_action.sa_handler = sigill_handler;
115
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000117
118 static int ret = 0;
119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000121 /* If this traps, we will return a second time from setjmp() with 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000123 ret = 1;
124 }
125
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 sigaction(SIGILL, &old_action, NULL);
127 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000128
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000130}
131#else
132#warning "No mechanism to detect A64_CRYPTO found, using C code only"
133#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
134#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
135
136#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
137
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200138#if !defined(MBEDTLS_SHA256_ALT)
139
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000140#define SHA256_BLOCK_SIZE 64
141
Gilles Peskine449bd832023-01-11 14:50:10 +0100142void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200143{
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200145}
146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200148{
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200150 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200154}
155
Gilles Peskine449bd832023-01-11 14:50:10 +0100156void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
157 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200158{
159 *dst = *src;
160}
161
Paul Bakker5121ce52009-01-03 21:22:43 +0000162/*
163 * SHA-256 context setup
164 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100165int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000166{
Valerio Settia3f99592022-12-14 10:56:54 +0100167#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100169 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 }
Valerio Settia3f99592022-12-14 10:56:54 +0100171#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100173 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 }
Valerio Settia3f99592022-12-14 10:56:54 +0100175#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100177 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200179#endif
180
Paul Bakker5121ce52009-01-03 21:22:43 +0000181 ctx->total[0] = 0;
182 ctx->total[1] = 0;
183
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100185#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000186 ctx->state[0] = 0x6A09E667;
187 ctx->state[1] = 0xBB67AE85;
188 ctx->state[2] = 0x3C6EF372;
189 ctx->state[3] = 0xA54FF53A;
190 ctx->state[4] = 0x510E527F;
191 ctx->state[5] = 0x9B05688C;
192 ctx->state[6] = 0x1F83D9AB;
193 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100194#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200196#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000197 ctx->state[0] = 0xC1059ED8;
198 ctx->state[1] = 0x367CD507;
199 ctx->state[2] = 0x3070DD17;
200 ctx->state[3] = 0xF70E5939;
201 ctx->state[4] = 0xFFC00B31;
202 ctx->state[5] = 0x68581511;
203 ctx->state[6] = 0x64F98FA7;
204 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200205#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000206 }
207
Valerio Settia3f99592022-12-14 10:56:54 +0100208#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000209 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100210#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000213}
214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200216static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000217{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200218 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
219 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
220 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
221 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
222 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
223 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
224 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
225 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
226 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
227 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
228 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
229 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
230 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
231 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
232 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
233 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
234};
Paul Bakker5121ce52009-01-03 21:22:43 +0000235
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000236#endif
237
238#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
239 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
240
241#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
242# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
243# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
244#endif
245
246static size_t mbedtls_internal_sha256_process_many_a64_crypto(
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000248{
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
250 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000251
252 size_t processed = 0;
253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000255 len >= SHA256_BLOCK_SIZE;
256 processed += SHA256_BLOCK_SIZE,
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 msg += SHA256_BLOCK_SIZE,
258 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000259 uint32x4_t tmp, abcd_prev;
260
261 uint32x4_t abcd_orig = abcd;
262 uint32x4_t efgh_orig = efgh;
263
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
265 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
266 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
267 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000268
269#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
270 /* Untested on BE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
272 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
273 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
274 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000275#endif
276
277 /* Rounds 0 to 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000279 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
281 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000282
283 /* Rounds 4 to 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000285 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
287 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000288
289 /* Rounds 8 to 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000291 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
293 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000294
295 /* Rounds 12 to 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000297 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
299 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000302 /* Rounds t to t + 3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
304 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000305 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
307 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000308
309 /* Rounds t + 4 to t + 7 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
311 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 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 t + 8 to t + 11 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
318 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000319 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
321 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000322
323 /* Rounds t + 12 to t + 15 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
325 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000326 abcd_prev = abcd;
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
328 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000329 }
330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 abcd = vaddq_u32(abcd, abcd_orig);
332 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000333 }
334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 vst1q_u32(&ctx->state[0], abcd);
336 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000339}
340
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100341#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
342/*
343 * This function is for internal use only if we are building both C and A64
344 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
345 */
346static
347#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100348int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
349 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000350{
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
352 SHA256_BLOCK_SIZE) ==
353 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000354}
355
356#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
357
358
359#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
360#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
361#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
362#endif
363
364
365#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
366 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
367
Gilles Peskine449bd832023-01-11 14:50:10 +0100368#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
369#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
372#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
375#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
378#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200380#define R(t) \
381 ( \
382 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
383 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200387 do \
388 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
390 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200391 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000393
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100394#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
395/*
396 * This function is for internal use only if we are building both C and A64
397 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
398 */
399static
400#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100401int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
402 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200403{
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200405 uint32_t temp1, temp2, W[64];
406 uint32_t A[8];
407 } local;
408
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200409 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200412 local.A[i] = ctx->state[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200414
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200415#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 for (i = 0; i < 64; i++) {
417 if (i < 16) {
418 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
419 } else {
420 R(i);
421 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
424 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200425
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200426 local.temp1 = local.A[7]; local.A[7] = local.A[6];
427 local.A[6] = local.A[5]; local.A[5] = local.A[4];
428 local.A[4] = local.A[3]; local.A[3] = local.A[2];
429 local.A[2] = local.A[1]; local.A[1] = local.A[0];
430 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200431 }
432#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 for (i = 0; i < 16; i++) {
434 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200435 }
436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 for (i = 0; i < 16; i += 8) {
438 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
439 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
440 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
441 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
442 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
443 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
444 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
445 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
446 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
447 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
448 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
449 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
450 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
451 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
452 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
453 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
454 }
455
456 for (i = 16; i < 64; i += 8) {
457 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
458 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
459 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
460 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
461 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
462 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
463 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
464 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
465 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
466 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
467 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
468 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
469 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
470 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
471 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
472 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200473 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200474#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200477 ctx->state[i] += local.A[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100479
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200480 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000484}
Jaeden Amero041039f2018-02-19 15:28:08 +0000485
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000486#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
487
488
489#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
490
491static size_t mbedtls_internal_sha256_process_many_c(
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000493{
494 size_t processed = 0;
495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 while (len >= SHA256_BLOCK_SIZE) {
497 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
498 return 0;
499 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000500
501 data += SHA256_BLOCK_SIZE;
502 len -= SHA256_BLOCK_SIZE;
503
504 processed += SHA256_BLOCK_SIZE;
505 }
506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000508}
509
510#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
511
512
513#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
514
Gilles Peskine449bd832023-01-11 14:50:10 +0100515static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000516{
517 static int done = 0;
518 static int supported = 0;
519
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000521 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000522 done = 1;
523 }
524
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000526}
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
529 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000530{
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 if (mbedtls_a64_crypto_sha256_has_support()) {
532 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
533 } else {
534 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
535 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000536}
537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
539 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000540{
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 if (mbedtls_a64_crypto_sha256_has_support()) {
542 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
543 } else {
544 return mbedtls_internal_sha256_process_c(ctx, data);
545 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000546}
547
548#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
549
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
551/*
552 * SHA-256 process buffer
553 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100554int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
555 const unsigned char *input,
556 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000557{
Janos Follath24eed8d2019-11-22 13:21:35 +0000558 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000559 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000560 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 if (ilen == 0) {
563 return 0;
564 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
566 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000567 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000568
Paul Bakker5c2364c2012-10-01 14:41:15 +0000569 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 ctx->total[0] &= 0xFFFFFFFF;
571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000573 ctx->total[1]++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 if (left && ilen >= fill) {
577 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
580 return ret;
581 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100582
Paul Bakker5121ce52009-01-03 21:22:43 +0000583 input += fill;
584 ilen -= fill;
585 left = 0;
586 }
587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000589 size_t processed =
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 mbedtls_internal_sha256_process_many(ctx, input, ilen);
591 if (processed < SHA256_BLOCK_SIZE) {
592 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
593 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100594
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000595 input += processed;
596 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000597 }
598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 if (ilen > 0) {
600 memcpy((void *) (ctx->buffer + left), input, ilen);
601 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000604}
605
Paul Bakker5121ce52009-01-03 21:22:43 +0000606/*
607 * SHA-256 final digest
608 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100609int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
610 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000611{
Janos Follath24eed8d2019-11-22 13:21:35 +0000612 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200613 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000614 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200616 /*
617 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
618 */
619 used = ctx->total[0] & 0x3F;
620
621 ctx->buffer[used++] = 0x80;
622
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200624 /* Enough room for padding + length in current block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 memset(ctx->buffer + used, 0, 56 - used);
626 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200627 /* We'll need an extra block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
631 return ret;
632 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200635 }
636
637 /*
638 * Add message length
639 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 high = (ctx->total[0] >> 29)
641 | (ctx->total[1] << 3);
642 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
645 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
648 return ret;
649 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100650
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200651 /*
652 * Output final state
653 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
655 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
656 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
657 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
658 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
659 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
660 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
David Horstmann687262c2022-10-06 17:54:57 +0100662 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200663#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100664 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200665#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 if (!truncated) {
667 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
668 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100669
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000671}
672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200674
Paul Bakker5121ce52009-01-03 21:22:43 +0000675/*
676 * output = SHA-256( input buffer )
677 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100678int mbedtls_sha256(const unsigned char *input,
679 size_t ilen,
680 unsigned char *output,
681 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000682{
Janos Follath24eed8d2019-11-22 13:21:35 +0000683 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000685
Valerio Settia3f99592022-12-14 10:56:54 +0100686#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100688 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 }
Valerio Settia3f99592022-12-14 10:56:54 +0100690#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100692 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 }
Valerio Settia3f99592022-12-14 10:56:54 +0100694#else /* defined MBEDTLS_SHA224_C only */
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100696 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200698#endif
699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100701
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100703 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100707 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100709
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100711 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100713
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100714exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000718}
719
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000721/*
722 * FIPS-180-2 test vectors
723 */
Valerio Settia3f99592022-12-14 10:56:54 +0100724static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000725{
726 { "abc" },
727 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
728 { "" }
729};
730
Valerio Settia3f99592022-12-14 10:56:54 +0100731static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000732{
733 3, 56, 1000
734};
735
Valerio Settia3f99592022-12-14 10:56:54 +0100736typedef const unsigned char (sha_test_sum_t)[32];
737
738/*
739 * SHA-224 test vectors
740 */
741#if defined(MBEDTLS_SHA224_C)
742static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000743{
Paul Bakker5121ce52009-01-03 21:22:43 +0000744 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
745 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
746 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
747 0xE3, 0x6C, 0x9D, 0xA7 },
748 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
749 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
750 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
751 0x52, 0x52, 0x25, 0x25 },
752 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
753 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
754 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100755 0x4E, 0xE7, 0xAD, 0x67 }
756};
757#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
Valerio Settia3f99592022-12-14 10:56:54 +0100759/*
760 * SHA-256 test vectors
761 */
762#if defined(MBEDTLS_SHA256_C)
763static sha_test_sum_t sha256_test_sum[] =
764{
Paul Bakker5121ce52009-01-03 21:22:43 +0000765 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
766 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
767 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
768 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
769 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
770 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
771 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
772 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
773 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
774 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
775 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
776 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
777};
Valerio Settia3f99592022-12-14 10:56:54 +0100778#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
780/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000781 * Checkup routine
782 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100783static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000784{
Valerio Settia3f99592022-12-14 10:56:54 +0100785 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500786 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200787 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000789
Valerio Settia3f99592022-12-14 10:56:54 +0100790#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100792#elif defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100794#else
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100796#endif
797
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 buf = mbedtls_calloc(1024, sizeof(unsigned char));
799 if (NULL == buf) {
800 if (verbose != 0) {
801 mbedtls_printf("Buffer allocation failed\n");
802 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500805 }
806
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 for (i = 0; i < 3; i++) {
810 if (verbose != 0) {
811 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
812 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100815 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000817
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 if (i == 2) {
819 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000820
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 for (int j = 0; j < 1000; j++) {
822 ret = mbedtls_sha256_update(&ctx, buf, buflen);
823 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100824 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100826 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 } else {
829 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
830 sha_test_buflen[i]);
831 if (ret != 0) {
832 goto fail;
833 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100834 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100837 goto fail;
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 }
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 (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100842 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100843 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100844 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 if (verbose != 0) {
847 mbedtls_printf("passed\n");
848 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000849 }
850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 if (verbose != 0) {
852 mbedtls_printf("\n");
853 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100855 goto exit;
856
857fail:
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 if (verbose != 0) {
859 mbedtls_printf("failed\n");
860 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100861
Paul Bakker5b4af392014-06-26 12:09:34 +0200862exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 mbedtls_sha256_free(&ctx);
864 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000867}
868
Valerio Settia3f99592022-12-14 10:56:54 +0100869#if defined(MBEDTLS_SHA256_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100870int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100871{
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100873}
874#endif /* MBEDTLS_SHA256_C */
875
876#if defined(MBEDTLS_SHA224_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100877int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100878{
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100880}
881#endif /* MBEDTLS_SHA224_C */
882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000884
Valerio Settia3f99592022-12-14 10:56:54 +0100885#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */