blob: 159acccaeb38a9167195df23a22936c8b2ea7e5a [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 Eyckb0563632024-06-13 16:20:14 +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 Eyckb0563632024-06-13 16:20:14 +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 Eyckb0563632024-06-13 16:20:14 +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 Eyckb0563632024-06-13 16:20:14 +020044#endif /* defined(__clang__) && (__clang_major__ >= 4) */
45
46/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
Sungbae Yoo4d211f32024-11-19 02:47:55 +000047#if !defined(_GNU_SOURCE)
Tom Van Eyckb0563632024-06-13 16:20:14 +020048#define _GNU_SOURCE
Sungbae Yoo4d211f32024-11-19 02:47:55 +000049#endif
Tom Van Eyckb0563632024-06-13 16:20:14 +020050
Jerome Forissier79013242021-07-28 10:24:04 +020051#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020052
Jens Wiklander32b31802023-10-06 16:59:46 +020053#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +020054
55#include "mbedtls/sha256.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010056#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020057#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020058
59#include <string.h>
60
Jens Wiklander817466c2018-05-22 13:49:31 +020061#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020062
Tom Van Eyckb0563632024-06-13 16:20:14 +020063#if defined(MBEDTLS_ARCH_IS_ARMV8_A)
64
65# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
66 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
67# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
68# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
69# warning "Target does not support NEON instructions"
70# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
71# else
72# error "Target does not support NEON instructions"
73# endif
74# endif
75# endif
76
77# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
78 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander32b31802023-10-06 16:59:46 +020079/* *INDENT-OFF* */
Tom Van Eyckb0563632024-06-13 16:20:14 +020080
81# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
82# if defined(__ARMCOMPILER_VERSION)
83# if __ARMCOMPILER_VERSION <= 6090000
84# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
85# endif
86# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
87# define MBEDTLS_POP_TARGET_PRAGMA
88# elif defined(__clang__)
Jens Wiklander32b31802023-10-06 16:59:46 +020089# if __clang_major__ < 4
Tom Van Eyckb0563632024-06-13 16:20:14 +020090# error "A more recent Clang is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jens Wiklander32b31802023-10-06 16:59:46 +020091# endif
92# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
93# define MBEDTLS_POP_TARGET_PRAGMA
94# elif defined(__GNUC__)
95 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
96 * intrinsics are missing. Missing intrinsics could be worked around.
97 */
98# if __GNUC__ < 6
Tom Van Eyckb0563632024-06-13 16:20:14 +020099# error "A more recent GCC is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jens Wiklander32b31802023-10-06 16:59:46 +0200100# else
101# pragma GCC push_options
102# pragma GCC target ("arch=armv8-a+crypto")
103# define MBEDTLS_POP_TARGET_PRAGMA
104# endif
105# else
Tom Van Eyckb0563632024-06-13 16:20:14 +0200106# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
Jens Wiklander32b31802023-10-06 16:59:46 +0200107# endif
108# endif
109/* *INDENT-ON* */
Tom Van Eyckb0563632024-06-13 16:20:14 +0200110
Jens Wiklander32b31802023-10-06 16:59:46 +0200111# endif
Tom Van Eyckb0563632024-06-13 16:20:14 +0200112# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200113# if defined(__unix__)
114# if defined(__linux__)
115/* Our preferred method of detection is getauxval() */
116# include <sys/auxv.h>
Tom Van Eyckb0563632024-06-13 16:20:14 +0200117/* These are not always defined via sys/auxv.h */
118# if !defined(HWCAP_SHA2)
119# define HWCAP_SHA2 (1 << 6)
120# endif
121# if !defined(HWCAP2_SHA2)
122# define HWCAP2_SHA2 (1 << 3)
123# endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200124# endif
125/* Use SIGILL on Unix, and fall back to it on Linux */
126# include <signal.h>
127# endif
128# endif
Tom Van Eyckb0563632024-06-13 16:20:14 +0200129#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
130# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
131# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Jens Wiklander32b31802023-10-06 16:59:46 +0200132#endif
133
Tom Van Eyckb0563632024-06-13 16:20:14 +0200134#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200135/*
136 * Capability detection code comes early, so we can disable
Tom Van Eyckb0563632024-06-13 16:20:14 +0200137 * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found
Jens Wiklander32b31802023-10-06 16:59:46 +0200138 */
Tom Van Eyckb0563632024-06-13 16:20:14 +0200139#if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2)
Jens Wiklander32b31802023-10-06 16:59:46 +0200140static int mbedtls_a64_crypto_sha256_determine_support(void)
141{
142 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
143}
Tom Van Eyckb0563632024-06-13 16:20:14 +0200144#elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2)
145static int mbedtls_a64_crypto_sha256_determine_support(void)
146{
147 return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0;
148}
Jens Wiklander32b31802023-10-06 16:59:46 +0200149#elif defined(__APPLE__)
150static int mbedtls_a64_crypto_sha256_determine_support(void)
151{
152 return 1;
153}
Tom Van Eyckb0563632024-06-13 16:20:14 +0200154#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
Sungbae Yoo4d211f32024-11-19 02:47:55 +0000155#ifndef WIN32_LEAN_AND_MEAN
Jens Wiklander32b31802023-10-06 16:59:46 +0200156#define WIN32_LEAN_AND_MEAN
Sungbae Yoo4d211f32024-11-19 02:47:55 +0000157#endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200158#include <Windows.h>
159#include <processthreadsapi.h>
160
161static int mbedtls_a64_crypto_sha256_determine_support(void)
162{
163 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
164 1 : 0;
165}
166#elif defined(__unix__) && defined(SIG_SETMASK)
167/* Detection with SIGILL, setjmp() and longjmp() */
168#include <signal.h>
169#include <setjmp.h>
170
171static jmp_buf return_from_sigill;
172
173/*
Tom Van Eyckb0563632024-06-13 16:20:14 +0200174 * Armv8-A SHA256 support detection via SIGILL
Jens Wiklander32b31802023-10-06 16:59:46 +0200175 */
176static void sigill_handler(int signal)
177{
178 (void) signal;
179 longjmp(return_from_sigill, 1);
180}
181
182static int mbedtls_a64_crypto_sha256_determine_support(void)
183{
184 struct sigaction old_action, new_action;
185
186 sigset_t old_mask;
187 if (sigprocmask(0, NULL, &old_mask)) {
188 return 0;
189 }
190
191 sigemptyset(&new_action.sa_mask);
192 new_action.sa_flags = 0;
193 new_action.sa_handler = sigill_handler;
194
195 sigaction(SIGILL, &new_action, &old_action);
196
197 static int ret = 0;
198
199 if (setjmp(return_from_sigill) == 0) { /* First return only */
200 /* If this traps, we will return a second time from setjmp() with 1 */
Tom Van Eyckb0563632024-06-13 16:20:14 +0200201#if defined(MBEDTLS_ARCH_IS_ARM64)
202 asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
203#else
204 asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
205#endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200206 ret = 1;
207 }
208
209 sigaction(SIGILL, &old_action, NULL);
210 sigprocmask(SIG_SETMASK, &old_mask, NULL);
211
212 return ret;
213}
214#else
Tom Van Eyckb0563632024-06-13 16:20:14 +0200215#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
216#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
Jens Wiklander32b31802023-10-06 16:59:46 +0200217#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
218
Tom Van Eyckb0563632024-06-13 16:20:14 +0200219#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Jens Wiklander817466c2018-05-22 13:49:31 +0200220
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100221#if !defined(MBEDTLS_SHA256_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +0200222
Jens Wiklander32b31802023-10-06 16:59:46 +0200223#define SHA256_BLOCK_SIZE 64
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100224
Jens Wiklander32b31802023-10-06 16:59:46 +0200225void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
226{
227 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200228}
229
Jens Wiklander32b31802023-10-06 16:59:46 +0200230void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200231{
Jens Wiklander32b31802023-10-06 16:59:46 +0200232 if (ctx == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200233 return;
Jens Wiklander32b31802023-10-06 16:59:46 +0200234 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200235
Jens Wiklander32b31802023-10-06 16:59:46 +0200236 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200237}
238
Jens Wiklander32b31802023-10-06 16:59:46 +0200239void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
240 const mbedtls_sha256_context *src)
Jens Wiklander817466c2018-05-22 13:49:31 +0200241{
242 *dst = *src;
243}
244
245/*
246 * SHA-256 context setup
247 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200248int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200249{
Jens Wiklander32b31802023-10-06 16:59:46 +0200250#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
251 if (is224 != 0 && is224 != 1) {
252 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
253 }
254#elif defined(MBEDTLS_SHA256_C)
255 if (is224 != 0) {
256 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
257 }
258#else /* defined MBEDTLS_SHA224_C only */
259 if (is224 == 0) {
260 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
261 }
262#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100263
Jens Wiklander817466c2018-05-22 13:49:31 +0200264 ctx->total[0] = 0;
265 ctx->total[1] = 0;
266
Jens Wiklander32b31802023-10-06 16:59:46 +0200267 if (is224 == 0) {
268#if defined(MBEDTLS_SHA256_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200269 ctx->state[0] = 0x6A09E667;
270 ctx->state[1] = 0xBB67AE85;
271 ctx->state[2] = 0x3C6EF372;
272 ctx->state[3] = 0xA54FF53A;
273 ctx->state[4] = 0x510E527F;
274 ctx->state[5] = 0x9B05688C;
275 ctx->state[6] = 0x1F83D9AB;
276 ctx->state[7] = 0x5BE0CD19;
Jens Wiklander32b31802023-10-06 16:59:46 +0200277#endif
278 } else {
279#if defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200280 ctx->state[0] = 0xC1059ED8;
281 ctx->state[1] = 0x367CD507;
282 ctx->state[2] = 0x3070DD17;
283 ctx->state[3] = 0xF70E5939;
284 ctx->state[4] = 0xFFC00B31;
285 ctx->state[5] = 0x68581511;
286 ctx->state[6] = 0x64F98FA7;
287 ctx->state[7] = 0xBEFA4FA4;
Jens Wiklander32b31802023-10-06 16:59:46 +0200288#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200289 }
290
Jens Wiklander32b31802023-10-06 16:59:46 +0200291#if defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200292 ctx->is224 = is224;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100293#endif
294
Jens Wiklander32b31802023-10-06 16:59:46 +0200295 return 0;
296}
297
Jens Wiklander817466c2018-05-22 13:49:31 +0200298#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
299static const uint32_t K[] =
300{
301 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
302 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
303 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
304 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
305 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
306 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
307 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
308 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
309 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
310 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
311 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
312 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
313 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
314 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
315 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
316 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
317};
318
Jens Wiklander32b31802023-10-06 16:59:46 +0200319#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200320
Tom Van Eyckb0563632024-06-13 16:20:14 +0200321#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
322 defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander817466c2018-05-22 13:49:31 +0200323
Tom Van Eyckb0563632024-06-13 16:20:14 +0200324#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander32b31802023-10-06 16:59:46 +0200325# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
326# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
327#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200328
Jens Wiklander32b31802023-10-06 16:59:46 +0200329static size_t mbedtls_internal_sha256_process_many_a64_crypto(
330 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
331{
332 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
333 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
334
335 size_t processed = 0;
336
337 for (;
338 len >= SHA256_BLOCK_SIZE;
339 processed += SHA256_BLOCK_SIZE,
340 msg += SHA256_BLOCK_SIZE,
341 len -= SHA256_BLOCK_SIZE) {
342 uint32x4_t tmp, abcd_prev;
343
344 uint32x4_t abcd_orig = abcd;
345 uint32x4_t efgh_orig = efgh;
346
Tom Van Eyckb0563632024-06-13 16:20:14 +0200347 uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
348 uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
349 uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
350 uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
Jens Wiklander32b31802023-10-06 16:59:46 +0200351
352#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
353 /* Untested on BE */
354 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
355 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
356 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
357 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
358#endif
359
360 /* Rounds 0 to 3 */
361 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
362 abcd_prev = abcd;
363 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
364 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
365
366 /* Rounds 4 to 7 */
367 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
368 abcd_prev = abcd;
369 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
370 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
371
372 /* Rounds 8 to 11 */
373 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
374 abcd_prev = abcd;
375 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
376 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
377
378 /* Rounds 12 to 15 */
379 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
380 abcd_prev = abcd;
381 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
382 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
383
384 for (int t = 16; t < 64; t += 16) {
385 /* Rounds t to t + 3 */
386 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
387 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
388 abcd_prev = abcd;
389 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
390 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
391
392 /* Rounds t + 4 to t + 7 */
393 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
394 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
395 abcd_prev = abcd;
396 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
397 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
398
399 /* Rounds t + 8 to t + 11 */
400 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
401 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
402 abcd_prev = abcd;
403 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
404 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
405
406 /* Rounds t + 12 to t + 15 */
407 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
408 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
409 abcd_prev = abcd;
410 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
411 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
412 }
413
414 abcd = vaddq_u32(abcd, abcd_orig);
415 efgh = vaddq_u32(efgh, efgh_orig);
416 }
417
418 vst1q_u32(&ctx->state[0], abcd);
419 vst1q_u32(&ctx->state[4], efgh);
420
421 return processed;
422}
423
Tom Van Eyckb0563632024-06-13 16:20:14 +0200424#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200425/*
Tom Van Eyckb0563632024-06-13 16:20:14 +0200426 * This function is for internal use only if we are building both C and Armv8-A
Jens Wiklander32b31802023-10-06 16:59:46 +0200427 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
428 */
429static
430#endif
431int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
432 const unsigned char data[SHA256_BLOCK_SIZE])
433{
434 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
435 SHA256_BLOCK_SIZE) ==
436 SHA256_BLOCK_SIZE) ? 0 : -1;
437}
438
Tom Van Eyckb0563632024-06-13 16:20:14 +0200439#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
440
Jens Wiklander32b31802023-10-06 16:59:46 +0200441#if defined(MBEDTLS_POP_TARGET_PRAGMA)
442#if defined(__clang__)
443#pragma clang attribute pop
444#elif defined(__GNUC__)
445#pragma GCC pop_options
446#endif
447#undef MBEDTLS_POP_TARGET_PRAGMA
448#endif
449
Tom Van Eyckb0563632024-06-13 16:20:14 +0200450#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200451#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
452#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
453#endif
454
455
456#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
Tom Van Eyckb0563632024-06-13 16:20:14 +0200457 !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander32b31802023-10-06 16:59:46 +0200458
459#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
460#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
461
462#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
463#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
464
465#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
466#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
467
468#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
469#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200470
Jerome Forissier79013242021-07-28 10:24:04 +0200471#define R(t) \
472 ( \
473 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
474 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200475 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200476
Jens Wiklander32b31802023-10-06 16:59:46 +0200477#define P(a, b, c, d, e, f, g, h, x, K) \
Jerome Forissier79013242021-07-28 10:24:04 +0200478 do \
479 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200480 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
481 local.temp2 = S2(a) + F0((a), (b), (c)); \
Jerome Forissier79013242021-07-28 10:24:04 +0200482 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Jens Wiklander32b31802023-10-06 16:59:46 +0200483 } while (0)
Jens Wiklander817466c2018-05-22 13:49:31 +0200484
Tom Van Eyckb0563632024-06-13 16:20:14 +0200485#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200486/*
Tom Van Eyckb0563632024-06-13 16:20:14 +0200487 * This function is for internal use only if we are building both C and Armv8
Jens Wiklander32b31802023-10-06 16:59:46 +0200488 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
489 */
490static
491#endif
492int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
493 const unsigned char data[SHA256_BLOCK_SIZE])
Jens Wiklander817466c2018-05-22 13:49:31 +0200494{
Jens Wiklander32b31802023-10-06 16:59:46 +0200495 struct {
Jerome Forissier79013242021-07-28 10:24:04 +0200496 uint32_t temp1, temp2, W[64];
497 uint32_t A[8];
498 } local;
499
Jens Wiklander817466c2018-05-22 13:49:31 +0200500 unsigned int i;
501
Jens Wiklander32b31802023-10-06 16:59:46 +0200502 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200503 local.A[i] = ctx->state[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200504 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200505
506#if defined(MBEDTLS_SHA256_SMALLER)
Jens Wiklander32b31802023-10-06 16:59:46 +0200507 for (i = 0; i < 64; i++) {
508 if (i < 16) {
509 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
510 } else {
511 R(i);
512 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200513
Jens Wiklander32b31802023-10-06 16:59:46 +0200514 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
515 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Jens Wiklander817466c2018-05-22 13:49:31 +0200516
Jerome Forissier79013242021-07-28 10:24:04 +0200517 local.temp1 = local.A[7]; local.A[7] = local.A[6];
518 local.A[6] = local.A[5]; local.A[5] = local.A[4];
519 local.A[4] = local.A[3]; local.A[3] = local.A[2];
520 local.A[2] = local.A[1]; local.A[1] = local.A[0];
521 local.A[0] = local.temp1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200522 }
523#else /* MBEDTLS_SHA256_SMALLER */
Jens Wiklander32b31802023-10-06 16:59:46 +0200524 for (i = 0; i < 16; i++) {
525 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Jens Wiklander817466c2018-05-22 13:49:31 +0200526 }
527
Jens Wiklander32b31802023-10-06 16:59:46 +0200528 for (i = 0; i < 16; i += 8) {
529 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
530 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
531 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
532 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
533 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
534 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
535 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
536 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
537 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
538 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
539 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
540 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
541 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
542 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
543 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
544 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
545 }
546
547 for (i = 16; i < 64; i += 8) {
548 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
549 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
550 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
551 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
552 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
553 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
554 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
555 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
556 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
557 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
558 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
559 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
560 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
561 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
562 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
563 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Jens Wiklander817466c2018-05-22 13:49:31 +0200564 }
565#endif /* MBEDTLS_SHA256_SMALLER */
566
Jens Wiklander32b31802023-10-06 16:59:46 +0200567 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200568 ctx->state[i] += local.A[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200569 }
Jerome Forissier79013242021-07-28 10:24:04 +0200570
571 /* Zeroise buffers and variables to clear sensitive data from memory. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200572 mbedtls_platform_zeroize(&local, sizeof(local));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100573
Jens Wiklander32b31802023-10-06 16:59:46 +0200574 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200575}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100576
Tom Van Eyckb0563632024-06-13 16:20:14 +0200577#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Jens Wiklander32b31802023-10-06 16:59:46 +0200578
579
Tom Van Eyckb0563632024-06-13 16:20:14 +0200580#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
Jens Wiklander32b31802023-10-06 16:59:46 +0200581
582static size_t mbedtls_internal_sha256_process_many_c(
583 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100584{
Jens Wiklander32b31802023-10-06 16:59:46 +0200585 size_t processed = 0;
586
587 while (len >= SHA256_BLOCK_SIZE) {
588 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
589 return 0;
590 }
591
592 data += SHA256_BLOCK_SIZE;
593 len -= SHA256_BLOCK_SIZE;
594
595 processed += SHA256_BLOCK_SIZE;
596 }
597
598 return processed;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100599}
Jens Wiklander32b31802023-10-06 16:59:46 +0200600
Tom Van Eyckb0563632024-06-13 16:20:14 +0200601#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
Jens Wiklander32b31802023-10-06 16:59:46 +0200602
603
Tom Van Eyckb0563632024-06-13 16:20:14 +0200604#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200605
606static int mbedtls_a64_crypto_sha256_has_support(void)
607{
608 static int done = 0;
609 static int supported = 0;
610
611 if (!done) {
612 supported = mbedtls_a64_crypto_sha256_determine_support();
613 done = 1;
614 }
615
616 return supported;
617}
618
619static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
620 const uint8_t *msg, size_t len)
621{
622 if (mbedtls_a64_crypto_sha256_has_support()) {
623 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
624 } else {
625 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
626 }
627}
628
629int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
630 const unsigned char data[SHA256_BLOCK_SIZE])
631{
632 if (mbedtls_a64_crypto_sha256_has_support()) {
633 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
634 } else {
635 return mbedtls_internal_sha256_process_c(ctx, data);
636 }
637}
638
Tom Van Eyckb0563632024-06-13 16:20:14 +0200639#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
Jens Wiklander32b31802023-10-06 16:59:46 +0200640
Jens Wiklander817466c2018-05-22 13:49:31 +0200641
642/*
643 * SHA-256 process buffer
644 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200645int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
646 const unsigned char *input,
647 size_t ilen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200648{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200649 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200650 size_t fill;
651 uint32_t left;
652
Jens Wiklander32b31802023-10-06 16:59:46 +0200653 if (ilen == 0) {
654 return 0;
655 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200656
657 left = ctx->total[0] & 0x3F;
Jens Wiklander32b31802023-10-06 16:59:46 +0200658 fill = SHA256_BLOCK_SIZE - left;
Jens Wiklander817466c2018-05-22 13:49:31 +0200659
660 ctx->total[0] += (uint32_t) ilen;
661 ctx->total[0] &= 0xFFFFFFFF;
662
Jens Wiklander32b31802023-10-06 16:59:46 +0200663 if (ctx->total[0] < (uint32_t) ilen) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200664 ctx->total[1]++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200665 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200666
Jens Wiklander32b31802023-10-06 16:59:46 +0200667 if (left && ilen >= fill) {
668 memcpy((void *) (ctx->buffer + left), input, fill);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100669
Jens Wiklander32b31802023-10-06 16:59:46 +0200670 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
671 return ret;
672 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100673
Jens Wiklander817466c2018-05-22 13:49:31 +0200674 input += fill;
675 ilen -= fill;
676 left = 0;
677 }
678
Jens Wiklander32b31802023-10-06 16:59:46 +0200679 while (ilen >= SHA256_BLOCK_SIZE) {
680 size_t processed =
681 mbedtls_internal_sha256_process_many(ctx, input, ilen);
682 if (processed < SHA256_BLOCK_SIZE) {
683 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
684 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100685
Jens Wiklander32b31802023-10-06 16:59:46 +0200686 input += processed;
687 ilen -= processed;
Jens Wiklander817466c2018-05-22 13:49:31 +0200688 }
689
Jens Wiklander32b31802023-10-06 16:59:46 +0200690 if (ilen > 0) {
691 memcpy((void *) (ctx->buffer + left), input, ilen);
692 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100693
Jens Wiklander32b31802023-10-06 16:59:46 +0200694 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200695}
696
Jens Wiklander817466c2018-05-22 13:49:31 +0200697/*
698 * SHA-256 final digest
699 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200700int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
701 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +0200702{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200703 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100704 uint32_t used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200705 uint32_t high, low;
Tom Van Eyckb0563632024-06-13 16:20:14 +0200706 int truncated = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200707
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100708 /*
709 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
710 */
711 used = ctx->total[0] & 0x3F;
712
713 ctx->buffer[used++] = 0x80;
714
Jens Wiklander32b31802023-10-06 16:59:46 +0200715 if (used <= 56) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100716 /* Enough room for padding + length in current block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200717 memset(ctx->buffer + used, 0, 56 - used);
718 } else {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100719 /* We'll need an extra block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200720 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100721
Jens Wiklander32b31802023-10-06 16:59:46 +0200722 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Tom Van Eyckb0563632024-06-13 16:20:14 +0200723 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200724 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100725
Jens Wiklander32b31802023-10-06 16:59:46 +0200726 memset(ctx->buffer, 0, 56);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100727 }
728
729 /*
730 * Add message length
731 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200732 high = (ctx->total[0] >> 29)
733 | (ctx->total[1] << 3);
734 low = (ctx->total[0] << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200735
Jens Wiklander32b31802023-10-06 16:59:46 +0200736 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
737 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Jens Wiklander817466c2018-05-22 13:49:31 +0200738
Jens Wiklander32b31802023-10-06 16:59:46 +0200739 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
Tom Van Eyckb0563632024-06-13 16:20:14 +0200740 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200741 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200742
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100743 /*
744 * Output final state
745 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200746 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
747 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
748 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
749 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
750 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
751 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
752 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Jens Wiklander817466c2018-05-22 13:49:31 +0200753
Jens Wiklander32b31802023-10-06 16:59:46 +0200754#if defined(MBEDTLS_SHA224_C)
755 truncated = ctx->is224;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100756#endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200757 if (!truncated) {
758 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
759 }
760
Tom Van Eyckb0563632024-06-13 16:20:14 +0200761 ret = 0;
762
763exit:
764 mbedtls_sha256_free(ctx);
765 return ret;
Jens Wiklander32b31802023-10-06 16:59:46 +0200766}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100767
Jens Wiklander817466c2018-05-22 13:49:31 +0200768#endif /* !MBEDTLS_SHA256_ALT */
769
770/*
771 * output = SHA-256( input buffer )
772 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200773int mbedtls_sha256(const unsigned char *input,
774 size_t ilen,
775 unsigned char *output,
776 int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200777{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200778 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200779 mbedtls_sha256_context ctx;
780
Jens Wiklander32b31802023-10-06 16:59:46 +0200781#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
782 if (is224 != 0 && is224 != 1) {
783 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
784 }
785#elif defined(MBEDTLS_SHA256_C)
786 if (is224 != 0) {
787 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
788 }
789#else /* defined MBEDTLS_SHA224_C only */
790 if (is224 == 0) {
791 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
792 }
793#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100794
Jens Wiklander32b31802023-10-06 16:59:46 +0200795 mbedtls_sha256_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100796
Jens Wiklander32b31802023-10-06 16:59:46 +0200797 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 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_update(&ctx, input, ilen)) != 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
Jens Wiklander32b31802023-10-06 16:59:46 +0200805 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100806 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200807 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100808
809exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200810 mbedtls_sha256_free(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100811
Jens Wiklander32b31802023-10-06 16:59:46 +0200812 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200813}
814
815#if defined(MBEDTLS_SELF_TEST)
816/*
817 * FIPS-180-2 test vectors
818 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200819static const unsigned char sha_test_buf[3][57] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200820{
821 { "abc" },
822 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
823 { "" }
824};
825
Jens Wiklander32b31802023-10-06 16:59:46 +0200826static const size_t sha_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200827{
828 3, 56, 1000
829};
830
Jens Wiklander32b31802023-10-06 16:59:46 +0200831typedef const unsigned char (sha_test_sum_t)[32];
832
833/*
834 * SHA-224 test vectors
835 */
836#if defined(MBEDTLS_SHA224_C)
837static sha_test_sum_t sha224_test_sum[] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200838{
Jens Wiklander817466c2018-05-22 13:49:31 +0200839 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
840 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
841 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
842 0xE3, 0x6C, 0x9D, 0xA7 },
843 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
844 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
845 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
846 0x52, 0x52, 0x25, 0x25 },
847 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
848 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
849 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Jens Wiklander32b31802023-10-06 16:59:46 +0200850 0x4E, 0xE7, 0xAD, 0x67 }
851};
852#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200853
Jens Wiklander32b31802023-10-06 16:59:46 +0200854/*
855 * SHA-256 test vectors
856 */
857#if defined(MBEDTLS_SHA256_C)
858static sha_test_sum_t sha256_test_sum[] =
859{
Jens Wiklander817466c2018-05-22 13:49:31 +0200860 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
861 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
862 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
863 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
864 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
865 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
866 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
867 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
868 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
869 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
870 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
871 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
872};
Jens Wiklander32b31802023-10-06 16:59:46 +0200873#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200874
875/*
876 * Checkup routine
877 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200878static int mbedtls_sha256_common_self_test(int verbose, int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200879{
Jens Wiklander32b31802023-10-06 16:59:46 +0200880 int i, buflen, ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200881 unsigned char *buf;
882 unsigned char sha256sum[32];
883 mbedtls_sha256_context ctx;
884
Jens Wiklander32b31802023-10-06 16:59:46 +0200885#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
886 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
887#elif defined(MBEDTLS_SHA256_C)
888 sha_test_sum_t *sha_test_sum = sha256_test_sum;
889#else
890 sha_test_sum_t *sha_test_sum = sha224_test_sum;
891#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200892
Jens Wiklander32b31802023-10-06 16:59:46 +0200893 buf = mbedtls_calloc(1024, sizeof(unsigned char));
894 if (NULL == buf) {
895 if (verbose != 0) {
896 mbedtls_printf("Buffer allocation failed\n");
897 }
898
899 return 1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200900 }
901
Jens Wiklander32b31802023-10-06 16:59:46 +0200902 mbedtls_sha256_init(&ctx);
Jens Wiklander817466c2018-05-22 13:49:31 +0200903
Jens Wiklander32b31802023-10-06 16:59:46 +0200904 for (i = 0; i < 3; i++) {
905 if (verbose != 0) {
906 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
907 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200908
Jens Wiklander32b31802023-10-06 16:59:46 +0200909 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100910 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200911 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200912
Jens Wiklander32b31802023-10-06 16:59:46 +0200913 if (i == 2) {
914 memset(buf, 'a', buflen = 1000);
Jens Wiklander817466c2018-05-22 13:49:31 +0200915
Jens Wiklander32b31802023-10-06 16:59:46 +0200916 for (int j = 0; j < 1000; j++) {
917 ret = mbedtls_sha256_update(&ctx, buf, buflen);
918 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100919 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200920 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100921 }
922
Jens Wiklander32b31802023-10-06 16:59:46 +0200923 } else {
924 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
925 sha_test_buflen[i]);
926 if (ret != 0) {
927 goto fail;
928 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100929 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200930
Jens Wiklander32b31802023-10-06 16:59:46 +0200931 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100932 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200933 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100934
Jens Wiklander817466c2018-05-22 13:49:31 +0200935
Jens Wiklander32b31802023-10-06 16:59:46 +0200936 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200937 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100938 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200939 }
940
Jens Wiklander32b31802023-10-06 16:59:46 +0200941 if (verbose != 0) {
942 mbedtls_printf("passed\n");
943 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200944 }
945
Jens Wiklander32b31802023-10-06 16:59:46 +0200946 if (verbose != 0) {
947 mbedtls_printf("\n");
948 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200949
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100950 goto exit;
951
952fail:
Jens Wiklander32b31802023-10-06 16:59:46 +0200953 if (verbose != 0) {
954 mbedtls_printf("failed\n");
955 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100956
Jens Wiklander817466c2018-05-22 13:49:31 +0200957exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200958 mbedtls_sha256_free(&ctx);
959 mbedtls_free(buf);
Jens Wiklander817466c2018-05-22 13:49:31 +0200960
Jens Wiklander32b31802023-10-06 16:59:46 +0200961 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200962}
963
Jens Wiklander32b31802023-10-06 16:59:46 +0200964#if defined(MBEDTLS_SHA256_C)
965int mbedtls_sha256_self_test(int verbose)
966{
967 return mbedtls_sha256_common_self_test(verbose, 0);
968}
969#endif /* MBEDTLS_SHA256_C */
970
971#if defined(MBEDTLS_SHA224_C)
972int mbedtls_sha224_self_test(int verbose)
973{
974 return mbedtls_sha256_common_self_test(verbose, 1);
975}
976#endif /* MBEDTLS_SHA224_C */
977
Jens Wiklander817466c2018-05-22 13:49:31 +0200978#endif /* MBEDTLS_SELF_TEST */
979
Jens Wiklander32b31802023-10-06 16:59:46 +0200980#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */