blob: 87889817a4eac6d143bc3318ae314183020d4724 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
Tom Van Eyckc1633172024-04-09 18:44:13 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Jens Wiklander817466c2018-05-22 13:49:31 +02006 */
7/*
8 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
9 *
10 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
11 */
12
Tom Van Eyckc1633172024-04-09 18:44:13 +020013#if defined(__clang__) && (__clang_major__ >= 4)
14
15/* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if,
16 * but that is defined by build_info.h, and we need this block to happen first. */
17#if defined(__ARM_ARCH) && (__ARM_ARCH_PROFILE == 'A')
18#if __ARM_ARCH >= 8
19#define MBEDTLS_SHA256_ARCH_IS_ARMV8_A
20#endif
21#endif
22
23#if defined(MBEDTLS_SHA256_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO)
Jens Wiklander32b31802023-10-06 16:59:46 +020024/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
25 *
26 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
27 * these are normally only enabled by the -march option on the command line.
28 * By defining the macros ourselves we gain access to those declarations without
29 * requiring -march on the command line.
30 *
Tom Van Eyckc1633172024-04-09 18:44:13 +020031 * `arm_neon.h` is included by common.h, so we put these defines
Jens Wiklander32b31802023-10-06 16:59:46 +020032 * at the top of this file, before any includes.
33 */
34#define __ARM_FEATURE_CRYPTO 1
35/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
36 *
37 * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
38 * for older compilers.
39 */
40#define __ARM_FEATURE_SHA2 1
41#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
42#endif
43
Tom Van Eyckc1633172024-04-09 18:44:13 +020044#endif /* defined(__clang__) && (__clang_major__ >= 4) */
45
46/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
47#define _GNU_SOURCE
48
Jerome Forissier79013242021-07-28 10:24:04 +020049#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020050
Jens Wiklander32b31802023-10-06 16:59:46 +020051#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +020052
53#include "mbedtls/sha256.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010054#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020055#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020056
57#include <string.h>
58
Jens Wiklander817466c2018-05-22 13:49:31 +020059#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020060
Tom Van Eyckc1633172024-04-09 18:44:13 +020061#if defined(MBEDTLS_ARCH_IS_ARMV8_A)
62
63# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
64 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
65# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
66# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
67# warning "Target does not support NEON instructions"
68# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
69# else
70# error "Target does not support NEON instructions"
71# endif
72# endif
73# endif
74
75# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
76 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander32b31802023-10-06 16:59:46 +020077/* *INDENT-OFF* */
Tom Van Eyckc1633172024-04-09 18:44:13 +020078
79# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
80# if defined(__ARMCOMPILER_VERSION)
81# if __ARMCOMPILER_VERSION <= 6090000
82# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
83# endif
84# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
85# define MBEDTLS_POP_TARGET_PRAGMA
86# elif defined(__clang__)
Jens Wiklander32b31802023-10-06 16:59:46 +020087# if __clang_major__ < 4
Tom Van Eyckc1633172024-04-09 18:44:13 +020088# error "A more recent Clang is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jens Wiklander32b31802023-10-06 16:59:46 +020089# endif
90# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
91# define MBEDTLS_POP_TARGET_PRAGMA
92# elif defined(__GNUC__)
93 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
94 * intrinsics are missing. Missing intrinsics could be worked around.
95 */
96# if __GNUC__ < 6
Tom Van Eyckc1633172024-04-09 18:44:13 +020097# error "A more recent GCC is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jens Wiklander32b31802023-10-06 16:59:46 +020098# else
99# pragma GCC push_options
100# pragma GCC target ("arch=armv8-a+crypto")
101# define MBEDTLS_POP_TARGET_PRAGMA
102# endif
103# else
Tom Van Eyckc1633172024-04-09 18:44:13 +0200104# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jens Wiklander32b31802023-10-06 16:59:46 +0200105# endif
106# endif
107/* *INDENT-ON* */
Tom Van Eyckc1633172024-04-09 18:44:13 +0200108
Jens Wiklander32b31802023-10-06 16:59:46 +0200109# endif
Tom Van Eyckc1633172024-04-09 18:44:13 +0200110# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200111# if defined(__unix__)
112# if defined(__linux__)
113/* Our preferred method of detection is getauxval() */
114# include <sys/auxv.h>
Tom Van Eyckc1633172024-04-09 18:44:13 +0200115/* These are not always defined via sys/auxv.h */
116# if !defined(HWCAP_SHA2)
117# define HWCAP_SHA2 (1 << 6)
118# endif
119# if !defined(HWCAP2_SHA2)
120# define HWCAP2_SHA2 (1 << 3)
121# endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200122# endif
123/* Use SIGILL on Unix, and fall back to it on Linux */
124# include <signal.h>
125# endif
126# endif
Tom Van Eyckc1633172024-04-09 18:44:13 +0200127#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
128# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
129# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Jens Wiklander32b31802023-10-06 16:59:46 +0200130#endif
131
Tom Van Eyckc1633172024-04-09 18:44:13 +0200132#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200133/*
134 * Capability detection code comes early, so we can disable
Tom Van Eyckc1633172024-04-09 18:44:13 +0200135 * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found
Jens Wiklander32b31802023-10-06 16:59:46 +0200136 */
Tom Van Eyckc1633172024-04-09 18:44:13 +0200137#if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2)
Jens Wiklander32b31802023-10-06 16:59:46 +0200138static int mbedtls_a64_crypto_sha256_determine_support(void)
139{
140 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
141}
Tom Van Eyckc1633172024-04-09 18:44:13 +0200142#elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2)
143static int mbedtls_a64_crypto_sha256_determine_support(void)
144{
145 return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0;
146}
Jens Wiklander32b31802023-10-06 16:59:46 +0200147#elif defined(__APPLE__)
148static int mbedtls_a64_crypto_sha256_determine_support(void)
149{
150 return 1;
151}
Tom Van Eyckc1633172024-04-09 18:44:13 +0200152#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Jens Wiklander32b31802023-10-06 16:59:46 +0200153#define WIN32_LEAN_AND_MEAN
154#include <Windows.h>
155#include <processthreadsapi.h>
156
157static int mbedtls_a64_crypto_sha256_determine_support(void)
158{
159 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
160 1 : 0;
161}
162#elif defined(__unix__) && defined(SIG_SETMASK)
163/* Detection with SIGILL, setjmp() and longjmp() */
164#include <signal.h>
165#include <setjmp.h>
166
167static jmp_buf return_from_sigill;
168
169/*
Tom Van Eyckc1633172024-04-09 18:44:13 +0200170 * Armv8-A SHA256 support detection via SIGILL
Jens Wiklander32b31802023-10-06 16:59:46 +0200171 */
172static void sigill_handler(int signal)
173{
174 (void) signal;
175 longjmp(return_from_sigill, 1);
176}
177
178static int mbedtls_a64_crypto_sha256_determine_support(void)
179{
180 struct sigaction old_action, new_action;
181
182 sigset_t old_mask;
183 if (sigprocmask(0, NULL, &old_mask)) {
184 return 0;
185 }
186
187 sigemptyset(&new_action.sa_mask);
188 new_action.sa_flags = 0;
189 new_action.sa_handler = sigill_handler;
190
191 sigaction(SIGILL, &new_action, &old_action);
192
193 static int ret = 0;
194
195 if (setjmp(return_from_sigill) == 0) { /* First return only */
196 /* If this traps, we will return a second time from setjmp() with 1 */
Tom Van Eyckc1633172024-04-09 18:44:13 +0200197#if defined(MBEDTLS_ARCH_IS_ARM64)
198 asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
199#else
200 asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
201#endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200202 ret = 1;
203 }
204
205 sigaction(SIGILL, &old_action, NULL);
206 sigprocmask(SIG_SETMASK, &old_mask, NULL);
207
208 return ret;
209}
210#else
Tom Van Eyckc1633172024-04-09 18:44:13 +0200211#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
212#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Jens Wiklander32b31802023-10-06 16:59:46 +0200213#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
214
Tom Van Eyckc1633172024-04-09 18:44:13 +0200215#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Jens Wiklander817466c2018-05-22 13:49:31 +0200216
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100217#if !defined(MBEDTLS_SHA256_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +0200218
Jens Wiklander32b31802023-10-06 16:59:46 +0200219#define SHA256_BLOCK_SIZE 64
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100220
Jens Wiklander32b31802023-10-06 16:59:46 +0200221void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
222{
223 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200224}
225
Jens Wiklander32b31802023-10-06 16:59:46 +0200226void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200227{
Jens Wiklander32b31802023-10-06 16:59:46 +0200228 if (ctx == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200229 return;
Jens Wiklander32b31802023-10-06 16:59:46 +0200230 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200231
Jens Wiklander32b31802023-10-06 16:59:46 +0200232 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200233}
234
Jens Wiklander32b31802023-10-06 16:59:46 +0200235void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
236 const mbedtls_sha256_context *src)
Jens Wiklander817466c2018-05-22 13:49:31 +0200237{
238 *dst = *src;
239}
240
241/*
242 * SHA-256 context setup
243 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200244int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200245{
Jens Wiklander32b31802023-10-06 16:59:46 +0200246#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
247 if (is224 != 0 && is224 != 1) {
248 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
249 }
250#elif defined(MBEDTLS_SHA256_C)
251 if (is224 != 0) {
252 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
253 }
254#else /* defined MBEDTLS_SHA224_C only */
255 if (is224 == 0) {
256 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
257 }
258#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100259
Jens Wiklander817466c2018-05-22 13:49:31 +0200260 ctx->total[0] = 0;
261 ctx->total[1] = 0;
262
Jens Wiklander32b31802023-10-06 16:59:46 +0200263 if (is224 == 0) {
264#if defined(MBEDTLS_SHA256_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200265 ctx->state[0] = 0x6A09E667;
266 ctx->state[1] = 0xBB67AE85;
267 ctx->state[2] = 0x3C6EF372;
268 ctx->state[3] = 0xA54FF53A;
269 ctx->state[4] = 0x510E527F;
270 ctx->state[5] = 0x9B05688C;
271 ctx->state[6] = 0x1F83D9AB;
272 ctx->state[7] = 0x5BE0CD19;
Jens Wiklander32b31802023-10-06 16:59:46 +0200273#endif
274 } else {
275#if defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200276 ctx->state[0] = 0xC1059ED8;
277 ctx->state[1] = 0x367CD507;
278 ctx->state[2] = 0x3070DD17;
279 ctx->state[3] = 0xF70E5939;
280 ctx->state[4] = 0xFFC00B31;
281 ctx->state[5] = 0x68581511;
282 ctx->state[6] = 0x64F98FA7;
283 ctx->state[7] = 0xBEFA4FA4;
Jens Wiklander32b31802023-10-06 16:59:46 +0200284#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200285 }
286
Jens Wiklander32b31802023-10-06 16:59:46 +0200287#if defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200288 ctx->is224 = is224;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100289#endif
290
Jens Wiklander32b31802023-10-06 16:59:46 +0200291 return 0;
292}
293
Jens Wiklander817466c2018-05-22 13:49:31 +0200294#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
295static const uint32_t K[] =
296{
297 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
298 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
299 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
300 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
301 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
302 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
303 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
304 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
305 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
306 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
307 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
308 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
309 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
310 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
311 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
312 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
313};
314
Jens Wiklander32b31802023-10-06 16:59:46 +0200315#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200316
Tom Van Eyckc1633172024-04-09 18:44:13 +0200317#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
318 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander817466c2018-05-22 13:49:31 +0200319
Tom Van Eyckc1633172024-04-09 18:44:13 +0200320#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander32b31802023-10-06 16:59:46 +0200321# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
322# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
323#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200324
Jens Wiklander32b31802023-10-06 16:59:46 +0200325static size_t mbedtls_internal_sha256_process_many_a64_crypto(
326 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
327{
328 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
329 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
330
331 size_t processed = 0;
332
333 for (;
334 len >= SHA256_BLOCK_SIZE;
335 processed += SHA256_BLOCK_SIZE,
336 msg += SHA256_BLOCK_SIZE,
337 len -= SHA256_BLOCK_SIZE) {
338 uint32x4_t tmp, abcd_prev;
339
340 uint32x4_t abcd_orig = abcd;
341 uint32x4_t efgh_orig = efgh;
342
Tom Van Eyckc1633172024-04-09 18:44:13 +0200343 uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
344 uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
345 uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
346 uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
Jens Wiklander32b31802023-10-06 16:59:46 +0200347
348#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
349 /* Untested on BE */
350 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
351 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
352 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
353 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
354#endif
355
356 /* Rounds 0 to 3 */
357 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
358 abcd_prev = abcd;
359 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
360 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
361
362 /* Rounds 4 to 7 */
363 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
364 abcd_prev = abcd;
365 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
366 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
367
368 /* Rounds 8 to 11 */
369 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
370 abcd_prev = abcd;
371 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
372 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
373
374 /* Rounds 12 to 15 */
375 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
376 abcd_prev = abcd;
377 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
378 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
379
380 for (int t = 16; t < 64; t += 16) {
381 /* Rounds t to t + 3 */
382 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
383 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
384 abcd_prev = abcd;
385 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
386 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
387
388 /* Rounds t + 4 to t + 7 */
389 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
390 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
391 abcd_prev = abcd;
392 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
393 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
394
395 /* Rounds t + 8 to t + 11 */
396 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
397 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
398 abcd_prev = abcd;
399 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
400 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
401
402 /* Rounds t + 12 to t + 15 */
403 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
404 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
405 abcd_prev = abcd;
406 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
407 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
408 }
409
410 abcd = vaddq_u32(abcd, abcd_orig);
411 efgh = vaddq_u32(efgh, efgh_orig);
412 }
413
414 vst1q_u32(&ctx->state[0], abcd);
415 vst1q_u32(&ctx->state[4], efgh);
416
417 return processed;
418}
419
Tom Van Eyckc1633172024-04-09 18:44:13 +0200420#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200421/*
Tom Van Eyckc1633172024-04-09 18:44:13 +0200422 * This function is for internal use only if we are building both C and Armv8-A
Jens Wiklander32b31802023-10-06 16:59:46 +0200423 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
424 */
425static
426#endif
427int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
428 const unsigned char data[SHA256_BLOCK_SIZE])
429{
430 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
431 SHA256_BLOCK_SIZE) ==
432 SHA256_BLOCK_SIZE) ? 0 : -1;
433}
434
Tom Van Eyckc1633172024-04-09 18:44:13 +0200435#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
436
Jens Wiklander32b31802023-10-06 16:59:46 +0200437#if defined(MBEDTLS_POP_TARGET_PRAGMA)
438#if defined(__clang__)
439#pragma clang attribute pop
440#elif defined(__GNUC__)
441#pragma GCC pop_options
442#endif
443#undef MBEDTLS_POP_TARGET_PRAGMA
444#endif
445
Tom Van Eyckc1633172024-04-09 18:44:13 +0200446#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200447#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
448#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
449#endif
450
451
452#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
Tom Van Eyckc1633172024-04-09 18:44:13 +0200453 !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander32b31802023-10-06 16:59:46 +0200454
455#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
456#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
457
458#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
459#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
460
461#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
462#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
463
464#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
465#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200466
Jerome Forissier79013242021-07-28 10:24:04 +0200467#define R(t) \
468 ( \
469 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
470 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200471 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200472
Jens Wiklander32b31802023-10-06 16:59:46 +0200473#define P(a, b, c, d, e, f, g, h, x, K) \
Jerome Forissier79013242021-07-28 10:24:04 +0200474 do \
475 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200476 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
477 local.temp2 = S2(a) + F0((a), (b), (c)); \
Jerome Forissier79013242021-07-28 10:24:04 +0200478 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Jens Wiklander32b31802023-10-06 16:59:46 +0200479 } while (0)
Jens Wiklander817466c2018-05-22 13:49:31 +0200480
Tom Van Eyckc1633172024-04-09 18:44:13 +0200481#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200482/*
Tom Van Eyckc1633172024-04-09 18:44:13 +0200483 * This function is for internal use only if we are building both C and Armv8
Jens Wiklander32b31802023-10-06 16:59:46 +0200484 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
485 */
486static
487#endif
488int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
489 const unsigned char data[SHA256_BLOCK_SIZE])
Jens Wiklander817466c2018-05-22 13:49:31 +0200490{
Jens Wiklander32b31802023-10-06 16:59:46 +0200491 struct {
Jerome Forissier79013242021-07-28 10:24:04 +0200492 uint32_t temp1, temp2, W[64];
493 uint32_t A[8];
494 } local;
495
Jens Wiklander817466c2018-05-22 13:49:31 +0200496 unsigned int i;
497
Jens Wiklander32b31802023-10-06 16:59:46 +0200498 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200499 local.A[i] = ctx->state[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200500 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200501
502#if defined(MBEDTLS_SHA256_SMALLER)
Jens Wiklander32b31802023-10-06 16:59:46 +0200503 for (i = 0; i < 64; i++) {
504 if (i < 16) {
505 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
506 } else {
507 R(i);
508 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200509
Jens Wiklander32b31802023-10-06 16:59:46 +0200510 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
511 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Jens Wiklander817466c2018-05-22 13:49:31 +0200512
Jerome Forissier79013242021-07-28 10:24:04 +0200513 local.temp1 = local.A[7]; local.A[7] = local.A[6];
514 local.A[6] = local.A[5]; local.A[5] = local.A[4];
515 local.A[4] = local.A[3]; local.A[3] = local.A[2];
516 local.A[2] = local.A[1]; local.A[1] = local.A[0];
517 local.A[0] = local.temp1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200518 }
519#else /* MBEDTLS_SHA256_SMALLER */
Jens Wiklander32b31802023-10-06 16:59:46 +0200520 for (i = 0; i < 16; i++) {
521 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Jens Wiklander817466c2018-05-22 13:49:31 +0200522 }
523
Jens Wiklander32b31802023-10-06 16:59:46 +0200524 for (i = 0; i < 16; i += 8) {
525 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
526 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
527 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
528 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
529 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
530 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
531 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
532 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
533 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
534 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
535 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
536 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
537 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
538 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
539 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
540 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
541 }
542
543 for (i = 16; i < 64; i += 8) {
544 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
545 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
546 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
547 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
548 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
549 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
550 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
551 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
552 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
553 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
554 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
555 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
556 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
557 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
558 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
559 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Jens Wiklander817466c2018-05-22 13:49:31 +0200560 }
561#endif /* MBEDTLS_SHA256_SMALLER */
562
Jens Wiklander32b31802023-10-06 16:59:46 +0200563 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200564 ctx->state[i] += local.A[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200565 }
Jerome Forissier79013242021-07-28 10:24:04 +0200566
567 /* Zeroise buffers and variables to clear sensitive data from memory. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200568 mbedtls_platform_zeroize(&local, sizeof(local));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100569
Jens Wiklander32b31802023-10-06 16:59:46 +0200570 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200571}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100572
Tom Van Eyckc1633172024-04-09 18:44:13 +0200573#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Jens Wiklander32b31802023-10-06 16:59:46 +0200574
575
Tom Van Eyckc1633172024-04-09 18:44:13 +0200576#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander32b31802023-10-06 16:59:46 +0200577
578static size_t mbedtls_internal_sha256_process_many_c(
579 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100580{
Jens Wiklander32b31802023-10-06 16:59:46 +0200581 size_t processed = 0;
582
583 while (len >= SHA256_BLOCK_SIZE) {
584 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
585 return 0;
586 }
587
588 data += SHA256_BLOCK_SIZE;
589 len -= SHA256_BLOCK_SIZE;
590
591 processed += SHA256_BLOCK_SIZE;
592 }
593
594 return processed;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100595}
Jens Wiklander32b31802023-10-06 16:59:46 +0200596
Tom Van Eyckc1633172024-04-09 18:44:13 +0200597#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Jens Wiklander32b31802023-10-06 16:59:46 +0200598
599
Tom Van Eyckc1633172024-04-09 18:44:13 +0200600#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200601
602static int mbedtls_a64_crypto_sha256_has_support(void)
603{
604 static int done = 0;
605 static int supported = 0;
606
607 if (!done) {
608 supported = mbedtls_a64_crypto_sha256_determine_support();
609 done = 1;
610 }
611
612 return supported;
613}
614
615static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
616 const uint8_t *msg, size_t len)
617{
618 if (mbedtls_a64_crypto_sha256_has_support()) {
619 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
620 } else {
621 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
622 }
623}
624
625int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
626 const unsigned char data[SHA256_BLOCK_SIZE])
627{
628 if (mbedtls_a64_crypto_sha256_has_support()) {
629 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
630 } else {
631 return mbedtls_internal_sha256_process_c(ctx, data);
632 }
633}
634
Tom Van Eyckc1633172024-04-09 18:44:13 +0200635#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Jens Wiklander32b31802023-10-06 16:59:46 +0200636
Jens Wiklander817466c2018-05-22 13:49:31 +0200637
638/*
639 * SHA-256 process buffer
640 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200641int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
642 const unsigned char *input,
643 size_t ilen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200644{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200645 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200646 size_t fill;
647 uint32_t left;
648
Jens Wiklander32b31802023-10-06 16:59:46 +0200649 if (ilen == 0) {
650 return 0;
651 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200652
653 left = ctx->total[0] & 0x3F;
Jens Wiklander32b31802023-10-06 16:59:46 +0200654 fill = SHA256_BLOCK_SIZE - left;
Jens Wiklander817466c2018-05-22 13:49:31 +0200655
656 ctx->total[0] += (uint32_t) ilen;
657 ctx->total[0] &= 0xFFFFFFFF;
658
Jens Wiklander32b31802023-10-06 16:59:46 +0200659 if (ctx->total[0] < (uint32_t) ilen) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200660 ctx->total[1]++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200661 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200662
Jens Wiklander32b31802023-10-06 16:59:46 +0200663 if (left && ilen >= fill) {
664 memcpy((void *) (ctx->buffer + left), input, fill);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100665
Jens Wiklander32b31802023-10-06 16:59:46 +0200666 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
667 return ret;
668 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100669
Jens Wiklander817466c2018-05-22 13:49:31 +0200670 input += fill;
671 ilen -= fill;
672 left = 0;
673 }
674
Jens Wiklander32b31802023-10-06 16:59:46 +0200675 while (ilen >= SHA256_BLOCK_SIZE) {
676 size_t processed =
677 mbedtls_internal_sha256_process_many(ctx, input, ilen);
678 if (processed < SHA256_BLOCK_SIZE) {
679 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
680 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100681
Jens Wiklander32b31802023-10-06 16:59:46 +0200682 input += processed;
683 ilen -= processed;
Jens Wiklander817466c2018-05-22 13:49:31 +0200684 }
685
Jens Wiklander32b31802023-10-06 16:59:46 +0200686 if (ilen > 0) {
687 memcpy((void *) (ctx->buffer + left), input, ilen);
688 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100689
Jens Wiklander32b31802023-10-06 16:59:46 +0200690 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200691}
692
Jens Wiklander817466c2018-05-22 13:49:31 +0200693/*
694 * SHA-256 final digest
695 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200696int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
697 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +0200698{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200699 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100700 uint32_t used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200701 uint32_t high, low;
Tom Van Eyckc1633172024-04-09 18:44:13 +0200702 int truncated = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200703
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100704 /*
705 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
706 */
707 used = ctx->total[0] & 0x3F;
708
709 ctx->buffer[used++] = 0x80;
710
Jens Wiklander32b31802023-10-06 16:59:46 +0200711 if (used <= 56) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100712 /* Enough room for padding + length in current block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200713 memset(ctx->buffer + used, 0, 56 - used);
714 } else {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100715 /* We'll need an extra block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200716 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100717
Jens Wiklander32b31802023-10-06 16:59:46 +0200718 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Tom Van Eyckc1633172024-04-09 18:44:13 +0200719 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200720 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100721
Jens Wiklander32b31802023-10-06 16:59:46 +0200722 memset(ctx->buffer, 0, 56);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100723 }
724
725 /*
726 * Add message length
727 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200728 high = (ctx->total[0] >> 29)
729 | (ctx->total[1] << 3);
730 low = (ctx->total[0] << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200731
Jens Wiklander32b31802023-10-06 16:59:46 +0200732 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
733 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Jens Wiklander817466c2018-05-22 13:49:31 +0200734
Jens Wiklander32b31802023-10-06 16:59:46 +0200735 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Tom Van Eyckc1633172024-04-09 18:44:13 +0200736 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200737 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200738
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100739 /*
740 * Output final state
741 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200742 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
743 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
744 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
745 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
746 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
747 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
748 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Jens Wiklander817466c2018-05-22 13:49:31 +0200749
Jens Wiklander32b31802023-10-06 16:59:46 +0200750#if defined(MBEDTLS_SHA224_C)
751 truncated = ctx->is224;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100752#endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200753 if (!truncated) {
754 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
755 }
756
Tom Van Eyckc1633172024-04-09 18:44:13 +0200757 ret = 0;
758
759exit:
760 mbedtls_sha256_free(ctx);
761 return ret;
Jens Wiklander32b31802023-10-06 16:59:46 +0200762}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100763
Jens Wiklander817466c2018-05-22 13:49:31 +0200764#endif /* !MBEDTLS_SHA256_ALT */
765
766/*
767 * output = SHA-256( input buffer )
768 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200769int mbedtls_sha256(const unsigned char *input,
770 size_t ilen,
771 unsigned char *output,
772 int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200773{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200774 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200775 mbedtls_sha256_context ctx;
776
Jens Wiklander32b31802023-10-06 16:59:46 +0200777#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
778 if (is224 != 0 && is224 != 1) {
779 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
780 }
781#elif defined(MBEDTLS_SHA256_C)
782 if (is224 != 0) {
783 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
784 }
785#else /* defined MBEDTLS_SHA224_C only */
786 if (is224 == 0) {
787 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
788 }
789#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100790
Jens Wiklander32b31802023-10-06 16:59:46 +0200791 mbedtls_sha256_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100792
Jens Wiklander32b31802023-10-06 16:59:46 +0200793 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100794 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200795 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100796
Jens Wiklander32b31802023-10-06 16:59:46 +0200797 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100798 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200799 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100800
Jens Wiklander32b31802023-10-06 16:59:46 +0200801 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100802 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200803 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100804
805exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200806 mbedtls_sha256_free(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100807
Jens Wiklander32b31802023-10-06 16:59:46 +0200808 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200809}
810
811#if defined(MBEDTLS_SELF_TEST)
812/*
813 * FIPS-180-2 test vectors
814 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200815static const unsigned char sha_test_buf[3][57] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200816{
817 { "abc" },
818 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
819 { "" }
820};
821
Jens Wiklander32b31802023-10-06 16:59:46 +0200822static const size_t sha_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200823{
824 3, 56, 1000
825};
826
Jens Wiklander32b31802023-10-06 16:59:46 +0200827typedef const unsigned char (sha_test_sum_t)[32];
828
829/*
830 * SHA-224 test vectors
831 */
832#if defined(MBEDTLS_SHA224_C)
833static sha_test_sum_t sha224_test_sum[] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200834{
Jens Wiklander817466c2018-05-22 13:49:31 +0200835 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
836 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
837 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
838 0xE3, 0x6C, 0x9D, 0xA7 },
839 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
840 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
841 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
842 0x52, 0x52, 0x25, 0x25 },
843 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
844 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
845 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Jens Wiklander32b31802023-10-06 16:59:46 +0200846 0x4E, 0xE7, 0xAD, 0x67 }
847};
848#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200849
Jens Wiklander32b31802023-10-06 16:59:46 +0200850/*
851 * SHA-256 test vectors
852 */
853#if defined(MBEDTLS_SHA256_C)
854static sha_test_sum_t sha256_test_sum[] =
855{
Jens Wiklander817466c2018-05-22 13:49:31 +0200856 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
857 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
858 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
859 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
860 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
861 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
862 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
863 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
864 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
865 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
866 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
867 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
868};
Jens Wiklander32b31802023-10-06 16:59:46 +0200869#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200870
871/*
872 * Checkup routine
873 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200874static int mbedtls_sha256_common_self_test(int verbose, int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200875{
Jens Wiklander32b31802023-10-06 16:59:46 +0200876 int i, buflen, ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200877 unsigned char *buf;
878 unsigned char sha256sum[32];
879 mbedtls_sha256_context ctx;
880
Jens Wiklander32b31802023-10-06 16:59:46 +0200881#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
882 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
883#elif defined(MBEDTLS_SHA256_C)
884 sha_test_sum_t *sha_test_sum = sha256_test_sum;
885#else
886 sha_test_sum_t *sha_test_sum = sha224_test_sum;
887#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200888
Jens Wiklander32b31802023-10-06 16:59:46 +0200889 buf = mbedtls_calloc(1024, sizeof(unsigned char));
890 if (NULL == buf) {
891 if (verbose != 0) {
892 mbedtls_printf("Buffer allocation failed\n");
893 }
894
895 return 1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200896 }
897
Jens Wiklander32b31802023-10-06 16:59:46 +0200898 mbedtls_sha256_init(&ctx);
Jens Wiklander817466c2018-05-22 13:49:31 +0200899
Jens Wiklander32b31802023-10-06 16:59:46 +0200900 for (i = 0; i < 3; i++) {
901 if (verbose != 0) {
902 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
903 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200904
Jens Wiklander32b31802023-10-06 16:59:46 +0200905 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100906 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200907 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200908
Jens Wiklander32b31802023-10-06 16:59:46 +0200909 if (i == 2) {
910 memset(buf, 'a', buflen = 1000);
Jens Wiklander817466c2018-05-22 13:49:31 +0200911
Jens Wiklander32b31802023-10-06 16:59:46 +0200912 for (int j = 0; j < 1000; j++) {
913 ret = mbedtls_sha256_update(&ctx, buf, buflen);
914 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100915 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200916 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100917 }
918
Jens Wiklander32b31802023-10-06 16:59:46 +0200919 } else {
920 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
921 sha_test_buflen[i]);
922 if (ret != 0) {
923 goto fail;
924 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100925 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200926
Jens Wiklander32b31802023-10-06 16:59:46 +0200927 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100928 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200929 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100930
Jens Wiklander817466c2018-05-22 13:49:31 +0200931
Jens Wiklander32b31802023-10-06 16:59:46 +0200932 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200933 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100934 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200935 }
936
Jens Wiklander32b31802023-10-06 16:59:46 +0200937 if (verbose != 0) {
938 mbedtls_printf("passed\n");
939 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200940 }
941
Jens Wiklander32b31802023-10-06 16:59:46 +0200942 if (verbose != 0) {
943 mbedtls_printf("\n");
944 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200945
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100946 goto exit;
947
948fail:
Jens Wiklander32b31802023-10-06 16:59:46 +0200949 if (verbose != 0) {
950 mbedtls_printf("failed\n");
951 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100952
Jens Wiklander817466c2018-05-22 13:49:31 +0200953exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200954 mbedtls_sha256_free(&ctx);
955 mbedtls_free(buf);
Jens Wiklander817466c2018-05-22 13:49:31 +0200956
Jens Wiklander32b31802023-10-06 16:59:46 +0200957 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200958}
959
Jens Wiklander32b31802023-10-06 16:59:46 +0200960#if defined(MBEDTLS_SHA256_C)
961int mbedtls_sha256_self_test(int verbose)
962{
963 return mbedtls_sha256_common_self_test(verbose, 0);
964}
965#endif /* MBEDTLS_SHA256_C */
966
967#if defined(MBEDTLS_SHA224_C)
968int mbedtls_sha224_self_test(int verbose)
969{
970 return mbedtls_sha256_common_self_test(verbose, 1);
971}
972#endif /* MBEDTLS_SHA224_C */
973
Jens Wiklander817466c2018-05-22 13:49:31 +0200974#endif /* MBEDTLS_SELF_TEST */
975
Jens Wiklander32b31802023-10-06 16:59:46 +0200976#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */