blob: 16fd20d8cd8eb9497170af322f1f0bd216fb780d [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) || \
David Horstmann8b6068b2023-01-05 15:42:32 +000039 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__)
David Horstmann8b6068b2023-01-05 15:42:32 +000045/* Our preferred method of detection is getauxval() */
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000046# include <sys/auxv.h>
47# endif
David Horstmann8b6068b2023-01-05 15:42:32 +000048/* 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) || \
David Horstmann8b6068b2023-01-05 15:42:32 +000054 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)
David Horstmann8b6068b2023-01-05 15:42:32 +000068static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000069{
David Horstmann8b6068b2023-01-05 15:42:32 +000070 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000071}
72#elif defined(__APPLE__)
David Horstmann8b6068b2023-01-05 15:42:32 +000073static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000074{
David Horstmann8b6068b2023-01-05 15:42:32 +000075 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
David Horstmann8b6068b2023-01-05 15:42:32 +000082static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000083{
David Horstmann8b6068b2023-01-05 15:42:32 +000084 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
David Horstmanne3d8f312023-01-03 11:07:09 +000092/* *INDENT-OFF* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000093#ifndef asm
94#define asm __asm__
95#endif
David Horstmanne3d8f312023-01-03 11:07:09 +000096/* *INDENT-ON* */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000097
98static jmp_buf return_from_sigill;
99
100/*
101 * A64 SHA256 support detection via SIGILL
102 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000103static void sigill_handler(int signal)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000104{
105 (void) signal;
David Horstmann8b6068b2023-01-05 15:42:32 +0000106 longjmp(return_from_sigill, 1);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000107}
108
David Horstmann8b6068b2023-01-05 15:42:32 +0000109static int mbedtls_a64_crypto_sha256_determine_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000110{
111 struct sigaction old_action, new_action;
112
113 sigset_t old_mask;
David Horstmann8b6068b2023-01-05 15:42:32 +0000114 if (sigprocmask(0, NULL, &old_mask)) {
115 return 0;
116 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000117
David Horstmann8b6068b2023-01-05 15:42:32 +0000118 sigemptyset(&new_action.sa_mask);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000119 new_action.sa_flags = 0;
120 new_action.sa_handler = sigill_handler;
121
David Horstmann8b6068b2023-01-05 15:42:32 +0000122 sigaction(SIGILL, &new_action, &old_action);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000123
124 static int ret = 0;
125
David Horstmann8b6068b2023-01-05 15:42:32 +0000126 if (setjmp(return_from_sigill) == 0) { /* First return only */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000127 /* If this traps, we will return a second time from setjmp() with 1 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000128 asm ("sha256h q0, q0, v0.4s" : : : "v0");
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000129 ret = 1;
130 }
131
David Horstmann8b6068b2023-01-05 15:42:32 +0000132 sigaction(SIGILL, &old_action, NULL);
133 sigprocmask(SIG_SETMASK, &old_mask, NULL);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000134
David Horstmann8b6068b2023-01-05 15:42:32 +0000135 return ret;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000136}
137#else
138#warning "No mechanism to detect A64_CRYPTO found, using C code only"
139#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
140#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
141
142#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
143
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200144#if !defined(MBEDTLS_SHA256_ALT)
145
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000146#define SHA256_BLOCK_SIZE 64
147
David Horstmann8b6068b2023-01-05 15:42:32 +0000148void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200149{
David Horstmann8b6068b2023-01-05 15:42:32 +0000150 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200151}
152
David Horstmann8b6068b2023-01-05 15:42:32 +0000153void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200154{
David Horstmann8b6068b2023-01-05 15:42:32 +0000155 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +0200156 return;
David Horstmann8b6068b2023-01-05 15:42:32 +0000157 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200158
David Horstmann8b6068b2023-01-05 15:42:32 +0000159 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200160}
161
David Horstmann8b6068b2023-01-05 15:42:32 +0000162void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
163 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200164{
165 *dst = *src;
166}
167
Paul Bakker5121ce52009-01-03 21:22:43 +0000168/*
169 * SHA-256 context setup
170 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000171int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000172{
Valerio Settia3f99592022-12-14 10:56:54 +0100173#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
David Horstmann8b6068b2023-01-05 15:42:32 +0000174 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100175 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
David Horstmann8b6068b2023-01-05 15:42:32 +0000176 }
Valerio Settia3f99592022-12-14 10:56:54 +0100177#elif defined(MBEDTLS_SHA256_C)
David Horstmann8b6068b2023-01-05 15:42:32 +0000178 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100179 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
David Horstmann8b6068b2023-01-05 15:42:32 +0000180 }
Valerio Settia3f99592022-12-14 10:56:54 +0100181#else /* defined MBEDTLS_SHA224_C only */
David Horstmann8b6068b2023-01-05 15:42:32 +0000182 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100183 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
David Horstmann8b6068b2023-01-05 15:42:32 +0000184 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200185#endif
186
Paul Bakker5121ce52009-01-03 21:22:43 +0000187 ctx->total[0] = 0;
188 ctx->total[1] = 0;
189
David Horstmann8b6068b2023-01-05 15:42:32 +0000190 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100191#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000192 ctx->state[0] = 0x6A09E667;
193 ctx->state[1] = 0xBB67AE85;
194 ctx->state[2] = 0x3C6EF372;
195 ctx->state[3] = 0xA54FF53A;
196 ctx->state[4] = 0x510E527F;
197 ctx->state[5] = 0x9B05688C;
198 ctx->state[6] = 0x1F83D9AB;
199 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100200#endif
David Horstmann8b6068b2023-01-05 15:42:32 +0000201 } else {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200202#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000203 ctx->state[0] = 0xC1059ED8;
204 ctx->state[1] = 0x367CD507;
205 ctx->state[2] = 0x3070DD17;
206 ctx->state[3] = 0xF70E5939;
207 ctx->state[4] = 0xFFC00B31;
208 ctx->state[5] = 0x68581511;
209 ctx->state[6] = 0x64F98FA7;
210 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200211#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000212 }
213
Valerio Settia3f99592022-12-14 10:56:54 +0100214#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100216#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100217
David Horstmann8b6068b2023-01-05 15:42:32 +0000218 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000219}
220
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200222static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000223{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200224 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
225 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
226 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
227 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
228 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
229 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
230 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
231 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
232 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
233 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
234 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
235 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
236 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
237 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
238 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
239 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
240};
Paul Bakker5121ce52009-01-03 21:22:43 +0000241
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000242#endif
243
244#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
245 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
246
247#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
248# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
249# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
250#endif
251
252static size_t mbedtls_internal_sha256_process_many_a64_crypto(
David Horstmann8b6068b2023-01-05 15:42:32 +0000253 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000254{
David Horstmann8b6068b2023-01-05 15:42:32 +0000255 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
256 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000257
258 size_t processed = 0;
259
David Horstmann8b6068b2023-01-05 15:42:32 +0000260 for (;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000261 len >= SHA256_BLOCK_SIZE;
262 processed += SHA256_BLOCK_SIZE,
David Horstmann8b6068b2023-01-05 15:42:32 +0000263 msg += SHA256_BLOCK_SIZE,
264 len -= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000265 uint32x4_t tmp, abcd_prev;
266
267 uint32x4_t abcd_orig = abcd;
268 uint32x4_t efgh_orig = efgh;
269
David Horstmann8b6068b2023-01-05 15:42:32 +0000270 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
271 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
272 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
273 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000274
275#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
276 /* Untested on BE */
David Horstmann8b6068b2023-01-05 15:42:32 +0000277 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
278 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
279 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
280 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000281#endif
282
283 /* Rounds 0 to 3 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000284 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000285 abcd_prev = abcd;
David Horstmann8b6068b2023-01-05 15:42:32 +0000286 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 4 to 7 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000290 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000291 abcd_prev = abcd;
David Horstmann8b6068b2023-01-05 15:42:32 +0000292 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 8 to 11 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000296 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000297 abcd_prev = abcd;
David Horstmann8b6068b2023-01-05 15:42:32 +0000298 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
299 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000300
301 /* Rounds 12 to 15 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000302 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000303 abcd_prev = abcd;
David Horstmann8b6068b2023-01-05 15:42:32 +0000304 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
305 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000306
David Horstmann8b6068b2023-01-05 15:42:32 +0000307 for (int t = 16; t < 64; t += 16) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000308 /* Rounds t to t + 3 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000309 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
310 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000311 abcd_prev = abcd;
David Horstmann8b6068b2023-01-05 15:42:32 +0000312 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
313 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000314
315 /* Rounds t + 4 to t + 7 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000316 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
317 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000318 abcd_prev = abcd;
David Horstmann8b6068b2023-01-05 15:42:32 +0000319 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
320 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000321
322 /* Rounds t + 8 to t + 11 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000323 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
324 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000325 abcd_prev = abcd;
David Horstmann8b6068b2023-01-05 15:42:32 +0000326 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
327 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000328
329 /* Rounds t + 12 to t + 15 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000330 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
331 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000332 abcd_prev = abcd;
David Horstmann8b6068b2023-01-05 15:42:32 +0000333 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
334 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000335 }
336
David Horstmann8b6068b2023-01-05 15:42:32 +0000337 abcd = vaddq_u32(abcd, abcd_orig);
338 efgh = vaddq_u32(efgh, efgh_orig);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000339 }
340
David Horstmann8b6068b2023-01-05 15:42:32 +0000341 vst1q_u32(&ctx->state[0], abcd);
342 vst1q_u32(&ctx->state[4], efgh);
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000343
David Horstmann8b6068b2023-01-05 15:42:32 +0000344 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000345}
346
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100347#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
348/*
349 * This function is for internal use only if we are building both C and A64
350 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
351 */
352static
353#endif
David Horstmann8b6068b2023-01-05 15:42:32 +0000354int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
355 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000356{
David Horstmann8b6068b2023-01-05 15:42:32 +0000357 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
358 SHA256_BLOCK_SIZE) ==
359 SHA256_BLOCK_SIZE) ? 0 : -1;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000360}
361
362#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
363
364
365#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
366#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
367#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
368#endif
369
370
371#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
372 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
373
David Horstmann8b6068b2023-01-05 15:42:32 +0000374#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
375#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
David Horstmann8b6068b2023-01-05 15:42:32 +0000377#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
378#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
David Horstmann8b6068b2023-01-05 15:42:32 +0000380#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
381#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000382
David Horstmann8b6068b2023-01-05 15:42:32 +0000383#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
384#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200386#define R(t) \
387 ( \
388 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
389 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100390 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
David Horstmann8b6068b2023-01-05 15:42:32 +0000392#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200393 do \
394 { \
David Horstmann8b6068b2023-01-05 15:42:32 +0000395 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
396 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200397 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
David Horstmann8b6068b2023-01-05 15:42:32 +0000398 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100400#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
401/*
402 * This function is for internal use only if we are building both C and A64
403 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
404 */
405static
406#endif
David Horstmann8b6068b2023-01-05 15:42:32 +0000407int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
408 const unsigned char data[SHA256_BLOCK_SIZE])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200409{
David Horstmann8b6068b2023-01-05 15:42:32 +0000410 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200411 uint32_t temp1, temp2, W[64];
412 uint32_t A[8];
413 } local;
414
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200415 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
David Horstmann8b6068b2023-01-05 15:42:32 +0000417 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200418 local.A[i] = ctx->state[i];
David Horstmann8b6068b2023-01-05 15:42:32 +0000419 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200420
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200421#if defined(MBEDTLS_SHA256_SMALLER)
David Horstmann8b6068b2023-01-05 15:42:32 +0000422 for (i = 0; i < 64; i++) {
423 if (i < 16) {
424 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
425 } else {
426 R(i);
427 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200428
David Horstmann8b6068b2023-01-05 15:42:32 +0000429 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
430 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200431
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200432 local.temp1 = local.A[7]; local.A[7] = local.A[6];
433 local.A[6] = local.A[5]; local.A[5] = local.A[4];
434 local.A[4] = local.A[3]; local.A[3] = local.A[2];
435 local.A[2] = local.A[1]; local.A[1] = local.A[0];
436 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200437 }
438#else /* MBEDTLS_SHA256_SMALLER */
David Horstmann8b6068b2023-01-05 15:42:32 +0000439 for (i = 0; i < 16; i++) {
440 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200441 }
442
David Horstmann8b6068b2023-01-05 15:42:32 +0000443 for (i = 0; i < 16; i += 8) {
444 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
445 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
446 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
447 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
448 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
449 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
450 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
451 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
452 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
453 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
454 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
455 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
456 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
457 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
458 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
459 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
460 }
461
462 for (i = 16; i < 64; i += 8) {
463 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
464 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
465 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
466 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
467 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
468 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
469 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
470 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
471 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
472 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
473 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
474 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
475 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
476 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
477 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
478 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200479 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200480#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200481
David Horstmann8b6068b2023-01-05 15:42:32 +0000482 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200483 ctx->state[i] += local.A[i];
David Horstmann8b6068b2023-01-05 15:42:32 +0000484 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100485
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200486 /* Zeroise buffers and variables to clear sensitive data from memory. */
David Horstmann8b6068b2023-01-05 15:42:32 +0000487 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100488
David Horstmann8b6068b2023-01-05 15:42:32 +0000489 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000490}
Jaeden Amero041039f2018-02-19 15:28:08 +0000491
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000492#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
493
494
495#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
496
497static size_t mbedtls_internal_sha256_process_many_c(
David Horstmann8b6068b2023-01-05 15:42:32 +0000498 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000499{
500 size_t processed = 0;
501
David Horstmann8b6068b2023-01-05 15:42:32 +0000502 while (len >= SHA256_BLOCK_SIZE) {
503 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
504 return 0;
505 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000506
507 data += SHA256_BLOCK_SIZE;
508 len -= SHA256_BLOCK_SIZE;
509
510 processed += SHA256_BLOCK_SIZE;
511 }
512
David Horstmann8b6068b2023-01-05 15:42:32 +0000513 return processed;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000514}
515
516#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
517
518
519#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
520
David Horstmann8b6068b2023-01-05 15:42:32 +0000521static int mbedtls_a64_crypto_sha256_has_support(void)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000522{
523 static int done = 0;
524 static int supported = 0;
525
David Horstmann8b6068b2023-01-05 15:42:32 +0000526 if (!done) {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000527 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000528 done = 1;
529 }
530
David Horstmann8b6068b2023-01-05 15:42:32 +0000531 return supported;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000532}
533
David Horstmann8b6068b2023-01-05 15:42:32 +0000534static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
535 const uint8_t *msg, size_t len)
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000536{
David Horstmann8b6068b2023-01-05 15:42:32 +0000537 if (mbedtls_a64_crypto_sha256_has_support()) {
538 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
539 } else {
540 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
541 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000542}
543
David Horstmann8b6068b2023-01-05 15:42:32 +0000544int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
545 const unsigned char data[SHA256_BLOCK_SIZE])
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000546{
David Horstmann8b6068b2023-01-05 15:42:32 +0000547 if (mbedtls_a64_crypto_sha256_has_support()) {
548 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
549 } else {
550 return mbedtls_internal_sha256_process_c(ctx, data);
551 }
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000552}
553
554#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
555
Paul Bakker5121ce52009-01-03 21:22:43 +0000556
557/*
558 * SHA-256 process buffer
559 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000560int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
561 const unsigned char *input,
562 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000563{
Janos Follath24eed8d2019-11-22 13:21:35 +0000564 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000565 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000566 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
David Horstmann8b6068b2023-01-05 15:42:32 +0000568 if (ilen == 0) {
569 return 0;
570 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
572 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000573 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
Paul Bakker5c2364c2012-10-01 14:41:15 +0000575 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000576 ctx->total[0] &= 0xFFFFFFFF;
577
David Horstmann8b6068b2023-01-05 15:42:32 +0000578 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 ctx->total[1]++;
David Horstmann8b6068b2023-01-05 15:42:32 +0000580 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
David Horstmann8b6068b2023-01-05 15:42:32 +0000582 if (left && ilen >= fill) {
583 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100584
David Horstmann8b6068b2023-01-05 15:42:32 +0000585 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
586 return ret;
587 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100588
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 input += fill;
590 ilen -= fill;
591 left = 0;
592 }
593
David Horstmann8b6068b2023-01-05 15:42:32 +0000594 while (ilen >= SHA256_BLOCK_SIZE) {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000595 size_t processed =
David Horstmann8b6068b2023-01-05 15:42:32 +0000596 mbedtls_internal_sha256_process_many(ctx, input, ilen);
597 if (processed < SHA256_BLOCK_SIZE) {
598 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
599 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100600
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000601 input += processed;
602 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000603 }
604
David Horstmann8b6068b2023-01-05 15:42:32 +0000605 if (ilen > 0) {
606 memcpy((void *) (ctx->buffer + left), input, ilen);
607 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100608
David Horstmann8b6068b2023-01-05 15:42:32 +0000609 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000610}
611
Paul Bakker5121ce52009-01-03 21:22:43 +0000612/*
613 * SHA-256 final digest
614 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000615int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
616 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000617{
Janos Follath24eed8d2019-11-22 13:21:35 +0000618 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200619 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000620 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200622 /*
623 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
624 */
625 used = ctx->total[0] & 0x3F;
626
627 ctx->buffer[used++] = 0x80;
628
David Horstmann8b6068b2023-01-05 15:42:32 +0000629 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200630 /* Enough room for padding + length in current block */
David Horstmann8b6068b2023-01-05 15:42:32 +0000631 memset(ctx->buffer + used, 0, 56 - used);
632 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200633 /* We'll need an extra block */
David Horstmann8b6068b2023-01-05 15:42:32 +0000634 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200635
David Horstmann8b6068b2023-01-05 15:42:32 +0000636 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
637 return ret;
638 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200639
David Horstmann8b6068b2023-01-05 15:42:32 +0000640 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200641 }
642
643 /*
644 * Add message length
645 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000646 high = (ctx->total[0] >> 29)
647 | (ctx->total[1] << 3);
648 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
David Horstmann8b6068b2023-01-05 15:42:32 +0000650 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
651 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
David Horstmann8b6068b2023-01-05 15:42:32 +0000653 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
654 return ret;
655 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100656
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200657 /*
658 * Output final state
659 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000660 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
661 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
662 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
663 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
664 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
665 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
666 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
David Horstmann687262c2022-10-06 17:54:57 +0100668 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200669#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100670 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200671#endif
David Horstmann8b6068b2023-01-05 15:42:32 +0000672 if (!truncated) {
673 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
674 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100675
David Horstmann8b6068b2023-01-05 15:42:32 +0000676 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000677}
678
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200680
Paul Bakker5121ce52009-01-03 21:22:43 +0000681/*
682 * output = SHA-256( input buffer )
683 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000684int mbedtls_sha256(const unsigned char *input,
685 size_t ilen,
686 unsigned char *output,
687 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000688{
Janos Follath24eed8d2019-11-22 13:21:35 +0000689 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Valerio Settia3f99592022-12-14 10:56:54 +0100692#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
David Horstmann8b6068b2023-01-05 15:42:32 +0000693 if (is224 != 0 && is224 != 1) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100694 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
David Horstmann8b6068b2023-01-05 15:42:32 +0000695 }
Valerio Settia3f99592022-12-14 10:56:54 +0100696#elif defined(MBEDTLS_SHA256_C)
David Horstmann8b6068b2023-01-05 15:42:32 +0000697 if (is224 != 0) {
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100698 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
David Horstmann8b6068b2023-01-05 15:42:32 +0000699 }
Valerio Settia3f99592022-12-14 10:56:54 +0100700#else /* defined MBEDTLS_SHA224_C only */
David Horstmann8b6068b2023-01-05 15:42:32 +0000701 if (is224 == 0) {
Valerio Settia3f99592022-12-14 10:56:54 +0100702 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
David Horstmann8b6068b2023-01-05 15:42:32 +0000703 }
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200704#endif
705
David Horstmann8b6068b2023-01-05 15:42:32 +0000706 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100707
David Horstmann8b6068b2023-01-05 15:42:32 +0000708 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100709 goto exit;
David Horstmann8b6068b2023-01-05 15:42:32 +0000710 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100711
David Horstmann8b6068b2023-01-05 15:42:32 +0000712 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100713 goto exit;
David Horstmann8b6068b2023-01-05 15:42:32 +0000714 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100715
David Horstmann8b6068b2023-01-05 15:42:32 +0000716 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100717 goto exit;
David Horstmann8b6068b2023-01-05 15:42:32 +0000718 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100719
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100720exit:
David Horstmann8b6068b2023-01-05 15:42:32 +0000721 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100722
David Horstmann8b6068b2023-01-05 15:42:32 +0000723 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000724}
725
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200726#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000727/*
728 * FIPS-180-2 test vectors
729 */
Valerio Settia3f99592022-12-14 10:56:54 +0100730static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000731{
732 { "abc" },
733 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
734 { "" }
735};
736
Valerio Settia3f99592022-12-14 10:56:54 +0100737static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000738{
739 3, 56, 1000
740};
741
Valerio Settia3f99592022-12-14 10:56:54 +0100742typedef const unsigned char (sha_test_sum_t)[32];
743
744/*
745 * SHA-224 test vectors
746 */
747#if defined(MBEDTLS_SHA224_C)
748static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000749{
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
751 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
752 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
753 0xE3, 0x6C, 0x9D, 0xA7 },
754 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
755 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
756 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
757 0x52, 0x52, 0x25, 0x25 },
758 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
759 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
760 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100761 0x4E, 0xE7, 0xAD, 0x67 }
762};
763#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000764
Valerio Settia3f99592022-12-14 10:56:54 +0100765/*
766 * SHA-256 test vectors
767 */
768#if defined(MBEDTLS_SHA256_C)
769static sha_test_sum_t sha256_test_sum[] =
770{
Paul Bakker5121ce52009-01-03 21:22:43 +0000771 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
772 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
773 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
774 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
775 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
776 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
777 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
778 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
779 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
780 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
781 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
782 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
783};
Valerio Settia3f99592022-12-14 10:56:54 +0100784#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
786/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000787 * Checkup routine
788 */
David Horstmann8b6068b2023-01-05 15:42:32 +0000789static int mbedtls_sha256_common_self_test(int verbose, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000790{
Valerio Settia3f99592022-12-14 10:56:54 +0100791 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500792 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200793 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000795
Valerio Settia3f99592022-12-14 10:56:54 +0100796#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
David Horstmann8b6068b2023-01-05 15:42:32 +0000797 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100798#elif defined(MBEDTLS_SHA256_C)
David Horstmann8b6068b2023-01-05 15:42:32 +0000799 sha_test_sum_t *sha_test_sum = sha256_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100800#else
David Horstmann8b6068b2023-01-05 15:42:32 +0000801 sha_test_sum_t *sha_test_sum = sha224_test_sum;
Valerio Settia3f99592022-12-14 10:56:54 +0100802#endif
803
David Horstmann8b6068b2023-01-05 15:42:32 +0000804 buf = mbedtls_calloc(1024, sizeof(unsigned char));
805 if (NULL == buf) {
806 if (verbose != 0) {
807 mbedtls_printf("Buffer allocation failed\n");
808 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500809
David Horstmann8b6068b2023-01-05 15:42:32 +0000810 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500811 }
812
David Horstmann8b6068b2023-01-05 15:42:32 +0000813 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200814
David Horstmann8b6068b2023-01-05 15:42:32 +0000815 for (i = 0; i < 3; i++) {
816 if (verbose != 0) {
817 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
818 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000819
David Horstmann8b6068b2023-01-05 15:42:32 +0000820 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100821 goto fail;
David Horstmann8b6068b2023-01-05 15:42:32 +0000822 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000823
David Horstmann8b6068b2023-01-05 15:42:32 +0000824 if (i == 2) {
825 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
David Horstmann8b6068b2023-01-05 15:42:32 +0000827 for (int j = 0; j < 1000; j++) {
828 ret = mbedtls_sha256_update(&ctx, buf, buflen);
829 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100830 goto fail;
David Horstmann8b6068b2023-01-05 15:42:32 +0000831 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100832 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100833
David Horstmann8b6068b2023-01-05 15:42:32 +0000834 } else {
835 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
836 sha_test_buflen[i]);
837 if (ret != 0) {
838 goto fail;
839 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100840 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000841
David Horstmann8b6068b2023-01-05 15:42:32 +0000842 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100843 goto fail;
David Horstmann8b6068b2023-01-05 15:42:32 +0000844 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100845
Paul Bakker5121ce52009-01-03 21:22:43 +0000846
David Horstmann8b6068b2023-01-05 15:42:32 +0000847 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100848 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100849 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100850 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000851
David Horstmann8b6068b2023-01-05 15:42:32 +0000852 if (verbose != 0) {
853 mbedtls_printf("passed\n");
854 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000855 }
856
David Horstmann8b6068b2023-01-05 15:42:32 +0000857 if (verbose != 0) {
858 mbedtls_printf("\n");
859 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000860
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100861 goto exit;
862
863fail:
David Horstmann8b6068b2023-01-05 15:42:32 +0000864 if (verbose != 0) {
865 mbedtls_printf("failed\n");
866 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100867
Paul Bakker5b4af392014-06-26 12:09:34 +0200868exit:
David Horstmann8b6068b2023-01-05 15:42:32 +0000869 mbedtls_sha256_free(&ctx);
870 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200871
David Horstmann8b6068b2023-01-05 15:42:32 +0000872 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000873}
874
Valerio Settia3f99592022-12-14 10:56:54 +0100875#if defined(MBEDTLS_SHA256_C)
David Horstmann8b6068b2023-01-05 15:42:32 +0000876int mbedtls_sha256_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100877{
David Horstmann8b6068b2023-01-05 15:42:32 +0000878 return mbedtls_sha256_common_self_test(verbose, 0);
Valerio Settia3f99592022-12-14 10:56:54 +0100879}
880#endif /* MBEDTLS_SHA256_C */
881
882#if defined(MBEDTLS_SHA224_C)
David Horstmann8b6068b2023-01-05 15:42:32 +0000883int mbedtls_sha224_self_test(int verbose)
Valerio Settia3f99592022-12-14 10:56:54 +0100884{
David Horstmann8b6068b2023-01-05 15:42:32 +0000885 return mbedtls_sha256_common_self_test(verbose, 1);
Valerio Settia3f99592022-12-14 10:56:54 +0100886}
887#endif /* MBEDTLS_SHA224_C */
888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Valerio Settia3f99592022-12-14 10:56:54 +0100891#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */