blob: 08822f4413db90e159febeaeb2b2fe0952987027 [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
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
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
Jens Wiklander32b31802023-10-06 16:59:46 +020025#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
26 defined(__clang__) && __clang_major__ >= 4
27/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
28 *
29 * The intrinsic declaration are guarded by predefined ACLE macros in clang:
30 * these are normally only enabled by the -march option on the command line.
31 * By defining the macros ourselves we gain access to those declarations without
32 * requiring -march on the command line.
33 *
34 * `arm_neon.h` could be included by any header file, so we put these defines
35 * at the top of this file, before any includes.
36 */
37#define __ARM_FEATURE_CRYPTO 1
38/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
39 *
40 * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
41 * for older compilers.
42 */
43#define __ARM_FEATURE_SHA2 1
44#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
45#endif
46
Jerome Forissier79013242021-07-28 10:24:04 +020047#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020048
Jens Wiklander32b31802023-10-06 16:59:46 +020049#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +020050
51#include "mbedtls/sha256.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010052#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020053#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020054
55#include <string.h>
56
Jens Wiklander817466c2018-05-22 13:49:31 +020057#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020058
Jens Wiklander32b31802023-10-06 16:59:46 +020059#if defined(__aarch64__)
60# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
61 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
62/* *INDENT-OFF* */
63# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
64# if defined(__clang__)
65# if __clang_major__ < 4
66# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
67# endif
68# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
69# define MBEDTLS_POP_TARGET_PRAGMA
70# elif defined(__GNUC__)
71 /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
72 * intrinsics are missing. Missing intrinsics could be worked around.
73 */
74# if __GNUC__ < 6
75# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
76# else
77# pragma GCC push_options
78# pragma GCC target ("arch=armv8-a+crypto")
79# define MBEDTLS_POP_TARGET_PRAGMA
80# endif
81# else
82# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
83# endif
84# endif
85/* *INDENT-ON* */
86# include <arm_neon.h>
87# endif
88# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
89# if defined(__unix__)
90# if defined(__linux__)
91/* Our preferred method of detection is getauxval() */
92# include <sys/auxv.h>
93# endif
94/* Use SIGILL on Unix, and fall back to it on Linux */
95# include <signal.h>
96# endif
97# endif
98#elif defined(_M_ARM64)
99# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
100 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
101# include <arm64_neon.h>
102# endif
103#else
104# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
105# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
106#endif
107
108#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
109/*
110 * Capability detection code comes early, so we can disable
111 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
112 */
113#if defined(HWCAP_SHA2)
114static int mbedtls_a64_crypto_sha256_determine_support(void)
115{
116 return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
117}
118#elif defined(__APPLE__)
119static int mbedtls_a64_crypto_sha256_determine_support(void)
120{
121 return 1;
122}
123#elif defined(_M_ARM64)
124#define WIN32_LEAN_AND_MEAN
125#include <Windows.h>
126#include <processthreadsapi.h>
127
128static int mbedtls_a64_crypto_sha256_determine_support(void)
129{
130 return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
131 1 : 0;
132}
133#elif defined(__unix__) && defined(SIG_SETMASK)
134/* Detection with SIGILL, setjmp() and longjmp() */
135#include <signal.h>
136#include <setjmp.h>
137
138static jmp_buf return_from_sigill;
139
140/*
141 * A64 SHA256 support detection via SIGILL
142 */
143static void sigill_handler(int signal)
144{
145 (void) signal;
146 longjmp(return_from_sigill, 1);
147}
148
149static int mbedtls_a64_crypto_sha256_determine_support(void)
150{
151 struct sigaction old_action, new_action;
152
153 sigset_t old_mask;
154 if (sigprocmask(0, NULL, &old_mask)) {
155 return 0;
156 }
157
158 sigemptyset(&new_action.sa_mask);
159 new_action.sa_flags = 0;
160 new_action.sa_handler = sigill_handler;
161
162 sigaction(SIGILL, &new_action, &old_action);
163
164 static int ret = 0;
165
166 if (setjmp(return_from_sigill) == 0) { /* First return only */
167 /* If this traps, we will return a second time from setjmp() with 1 */
168 asm ("sha256h q0, q0, v0.4s" : : : "v0");
169 ret = 1;
170 }
171
172 sigaction(SIGILL, &old_action, NULL);
173 sigprocmask(SIG_SETMASK, &old_mask, NULL);
174
175 return ret;
176}
177#else
178#warning "No mechanism to detect A64_CRYPTO found, using C code only"
179#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
180#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
181
182#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
Jens Wiklander817466c2018-05-22 13:49:31 +0200183
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100184#if !defined(MBEDTLS_SHA256_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +0200185
Jens Wiklander32b31802023-10-06 16:59:46 +0200186#define SHA256_BLOCK_SIZE 64
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100187
Jens Wiklander32b31802023-10-06 16:59:46 +0200188void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
189{
190 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200191}
192
Jens Wiklander32b31802023-10-06 16:59:46 +0200193void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200194{
Jens Wiklander32b31802023-10-06 16:59:46 +0200195 if (ctx == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200196 return;
Jens Wiklander32b31802023-10-06 16:59:46 +0200197 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200198
Jens Wiklander32b31802023-10-06 16:59:46 +0200199 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200200}
201
Jens Wiklander32b31802023-10-06 16:59:46 +0200202void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
203 const mbedtls_sha256_context *src)
Jens Wiklander817466c2018-05-22 13:49:31 +0200204{
205 *dst = *src;
206}
207
208/*
209 * SHA-256 context setup
210 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200211int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200212{
Jens Wiklander32b31802023-10-06 16:59:46 +0200213#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
214 if (is224 != 0 && is224 != 1) {
215 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
216 }
217#elif defined(MBEDTLS_SHA256_C)
218 if (is224 != 0) {
219 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
220 }
221#else /* defined MBEDTLS_SHA224_C only */
222 if (is224 == 0) {
223 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
224 }
225#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100226
Jens Wiklander817466c2018-05-22 13:49:31 +0200227 ctx->total[0] = 0;
228 ctx->total[1] = 0;
229
Jens Wiklander32b31802023-10-06 16:59:46 +0200230 if (is224 == 0) {
231#if defined(MBEDTLS_SHA256_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200232 ctx->state[0] = 0x6A09E667;
233 ctx->state[1] = 0xBB67AE85;
234 ctx->state[2] = 0x3C6EF372;
235 ctx->state[3] = 0xA54FF53A;
236 ctx->state[4] = 0x510E527F;
237 ctx->state[5] = 0x9B05688C;
238 ctx->state[6] = 0x1F83D9AB;
239 ctx->state[7] = 0x5BE0CD19;
Jens Wiklander32b31802023-10-06 16:59:46 +0200240#endif
241 } else {
242#if defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200243 ctx->state[0] = 0xC1059ED8;
244 ctx->state[1] = 0x367CD507;
245 ctx->state[2] = 0x3070DD17;
246 ctx->state[3] = 0xF70E5939;
247 ctx->state[4] = 0xFFC00B31;
248 ctx->state[5] = 0x68581511;
249 ctx->state[6] = 0x64F98FA7;
250 ctx->state[7] = 0xBEFA4FA4;
Jens Wiklander32b31802023-10-06 16:59:46 +0200251#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200252 }
253
Jens Wiklander32b31802023-10-06 16:59:46 +0200254#if defined(MBEDTLS_SHA224_C)
Jens Wiklander817466c2018-05-22 13:49:31 +0200255 ctx->is224 = is224;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100256#endif
257
Jens Wiklander32b31802023-10-06 16:59:46 +0200258 return 0;
259}
260
Jens Wiklander817466c2018-05-22 13:49:31 +0200261#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
262static const uint32_t K[] =
263{
264 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
265 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
266 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
267 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
268 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
269 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
270 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
271 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
272 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
273 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
274 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
275 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
276 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
277 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
278 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
279 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
280};
281
Jens Wiklander32b31802023-10-06 16:59:46 +0200282#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200283
Jens Wiklander32b31802023-10-06 16:59:46 +0200284#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
285 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
Jens Wiklander817466c2018-05-22 13:49:31 +0200286
Jens Wiklander32b31802023-10-06 16:59:46 +0200287#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
288# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
289# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
290#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200291
Jens Wiklander32b31802023-10-06 16:59:46 +0200292static size_t mbedtls_internal_sha256_process_many_a64_crypto(
293 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
294{
295 uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
296 uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
297
298 size_t processed = 0;
299
300 for (;
301 len >= SHA256_BLOCK_SIZE;
302 processed += SHA256_BLOCK_SIZE,
303 msg += SHA256_BLOCK_SIZE,
304 len -= SHA256_BLOCK_SIZE) {
305 uint32x4_t tmp, abcd_prev;
306
307 uint32x4_t abcd_orig = abcd;
308 uint32x4_t efgh_orig = efgh;
309
310 uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0);
311 uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1);
312 uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2);
313 uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3);
314
315#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
316 /* Untested on BE */
317 sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
318 sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
319 sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
320 sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
321#endif
322
323 /* Rounds 0 to 3 */
324 tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
325 abcd_prev = abcd;
326 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
327 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
328
329 /* Rounds 4 to 7 */
330 tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
331 abcd_prev = abcd;
332 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
333 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
334
335 /* Rounds 8 to 11 */
336 tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
337 abcd_prev = abcd;
338 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
339 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
340
341 /* Rounds 12 to 15 */
342 tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
343 abcd_prev = abcd;
344 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
345 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
346
347 for (int t = 16; t < 64; t += 16) {
348 /* Rounds t to t + 3 */
349 sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
350 tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
351 abcd_prev = abcd;
352 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
353 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
354
355 /* Rounds t + 4 to t + 7 */
356 sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
357 tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
358 abcd_prev = abcd;
359 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
360 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
361
362 /* Rounds t + 8 to t + 11 */
363 sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
364 tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
365 abcd_prev = abcd;
366 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
367 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
368
369 /* Rounds t + 12 to t + 15 */
370 sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
371 tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
372 abcd_prev = abcd;
373 abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
374 efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
375 }
376
377 abcd = vaddq_u32(abcd, abcd_orig);
378 efgh = vaddq_u32(efgh, efgh_orig);
379 }
380
381 vst1q_u32(&ctx->state[0], abcd);
382 vst1q_u32(&ctx->state[4], efgh);
383
384 return processed;
385}
386
387#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
388/*
389 * This function is for internal use only if we are building both C and A64
390 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
391 */
392static
393#endif
394int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
395 const unsigned char data[SHA256_BLOCK_SIZE])
396{
397 return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
398 SHA256_BLOCK_SIZE) ==
399 SHA256_BLOCK_SIZE) ? 0 : -1;
400}
401
402#if defined(MBEDTLS_POP_TARGET_PRAGMA)
403#if defined(__clang__)
404#pragma clang attribute pop
405#elif defined(__GNUC__)
406#pragma GCC pop_options
407#endif
408#undef MBEDTLS_POP_TARGET_PRAGMA
409#endif
410
411#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
412
413#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
414#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
415#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
416#endif
417
418
419#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
420 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
421
422#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
423#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
424
425#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
426#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
427
428#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
429#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
430
431#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
432#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200433
Jerome Forissier79013242021-07-28 10:24:04 +0200434#define R(t) \
435 ( \
436 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
437 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200438 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200439
Jens Wiklander32b31802023-10-06 16:59:46 +0200440#define P(a, b, c, d, e, f, g, h, x, K) \
Jerome Forissier79013242021-07-28 10:24:04 +0200441 do \
442 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200443 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
444 local.temp2 = S2(a) + F0((a), (b), (c)); \
Jerome Forissier79013242021-07-28 10:24:04 +0200445 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Jens Wiklander32b31802023-10-06 16:59:46 +0200446 } while (0)
Jens Wiklander817466c2018-05-22 13:49:31 +0200447
Jens Wiklander32b31802023-10-06 16:59:46 +0200448#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
449/*
450 * This function is for internal use only if we are building both C and A64
451 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
452 */
453static
454#endif
455int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
456 const unsigned char data[SHA256_BLOCK_SIZE])
Jens Wiklander817466c2018-05-22 13:49:31 +0200457{
Jens Wiklander32b31802023-10-06 16:59:46 +0200458 struct {
Jerome Forissier79013242021-07-28 10:24:04 +0200459 uint32_t temp1, temp2, W[64];
460 uint32_t A[8];
461 } local;
462
Jens Wiklander817466c2018-05-22 13:49:31 +0200463 unsigned int i;
464
Jens Wiklander32b31802023-10-06 16:59:46 +0200465 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200466 local.A[i] = ctx->state[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200467 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200468
469#if defined(MBEDTLS_SHA256_SMALLER)
Jens Wiklander32b31802023-10-06 16:59:46 +0200470 for (i = 0; i < 64; i++) {
471 if (i < 16) {
472 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
473 } else {
474 R(i);
475 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200476
Jens Wiklander32b31802023-10-06 16:59:46 +0200477 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
478 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Jens Wiklander817466c2018-05-22 13:49:31 +0200479
Jerome Forissier79013242021-07-28 10:24:04 +0200480 local.temp1 = local.A[7]; local.A[7] = local.A[6];
481 local.A[6] = local.A[5]; local.A[5] = local.A[4];
482 local.A[4] = local.A[3]; local.A[3] = local.A[2];
483 local.A[2] = local.A[1]; local.A[1] = local.A[0];
484 local.A[0] = local.temp1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200485 }
486#else /* MBEDTLS_SHA256_SMALLER */
Jens Wiklander32b31802023-10-06 16:59:46 +0200487 for (i = 0; i < 16; i++) {
488 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Jens Wiklander817466c2018-05-22 13:49:31 +0200489 }
490
Jens Wiklander32b31802023-10-06 16:59:46 +0200491 for (i = 0; i < 16; i += 8) {
492 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
493 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
494 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
495 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
496 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
497 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
498 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
499 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
500 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
501 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
502 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
503 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
504 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
505 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
506 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
507 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
508 }
509
510 for (i = 16; i < 64; i += 8) {
511 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
512 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
513 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
514 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
515 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
516 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
517 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
518 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
519 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
520 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
521 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
522 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
523 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
524 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
525 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
526 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Jens Wiklander817466c2018-05-22 13:49:31 +0200527 }
528#endif /* MBEDTLS_SHA256_SMALLER */
529
Jens Wiklander32b31802023-10-06 16:59:46 +0200530 for (i = 0; i < 8; i++) {
Jerome Forissier79013242021-07-28 10:24:04 +0200531 ctx->state[i] += local.A[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200532 }
Jerome Forissier79013242021-07-28 10:24:04 +0200533
534 /* Zeroise buffers and variables to clear sensitive data from memory. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200535 mbedtls_platform_zeroize(&local, sizeof(local));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100536
Jens Wiklander32b31802023-10-06 16:59:46 +0200537 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200538}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100539
Jens Wiklander32b31802023-10-06 16:59:46 +0200540#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
541
542
543#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
544
545static size_t mbedtls_internal_sha256_process_many_c(
546 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100547{
Jens Wiklander32b31802023-10-06 16:59:46 +0200548 size_t processed = 0;
549
550 while (len >= SHA256_BLOCK_SIZE) {
551 if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
552 return 0;
553 }
554
555 data += SHA256_BLOCK_SIZE;
556 len -= SHA256_BLOCK_SIZE;
557
558 processed += SHA256_BLOCK_SIZE;
559 }
560
561 return processed;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100562}
Jens Wiklander32b31802023-10-06 16:59:46 +0200563
564#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
565
566
567#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
568
569static int mbedtls_a64_crypto_sha256_has_support(void)
570{
571 static int done = 0;
572 static int supported = 0;
573
574 if (!done) {
575 supported = mbedtls_a64_crypto_sha256_determine_support();
576 done = 1;
577 }
578
579 return supported;
580}
581
582static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
583 const uint8_t *msg, size_t len)
584{
585 if (mbedtls_a64_crypto_sha256_has_support()) {
586 return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
587 } else {
588 return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
589 }
590}
591
592int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
593 const unsigned char data[SHA256_BLOCK_SIZE])
594{
595 if (mbedtls_a64_crypto_sha256_has_support()) {
596 return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
597 } else {
598 return mbedtls_internal_sha256_process_c(ctx, data);
599 }
600}
601
602#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
603
Jens Wiklander817466c2018-05-22 13:49:31 +0200604
605/*
606 * SHA-256 process buffer
607 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200608int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
609 const unsigned char *input,
610 size_t ilen)
Jens Wiklander817466c2018-05-22 13:49:31 +0200611{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200612 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200613 size_t fill;
614 uint32_t left;
615
Jens Wiklander32b31802023-10-06 16:59:46 +0200616 if (ilen == 0) {
617 return 0;
618 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200619
620 left = ctx->total[0] & 0x3F;
Jens Wiklander32b31802023-10-06 16:59:46 +0200621 fill = SHA256_BLOCK_SIZE - left;
Jens Wiklander817466c2018-05-22 13:49:31 +0200622
623 ctx->total[0] += (uint32_t) ilen;
624 ctx->total[0] &= 0xFFFFFFFF;
625
Jens Wiklander32b31802023-10-06 16:59:46 +0200626 if (ctx->total[0] < (uint32_t) ilen) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200627 ctx->total[1]++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200628 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200629
Jens Wiklander32b31802023-10-06 16:59:46 +0200630 if (left && ilen >= fill) {
631 memcpy((void *) (ctx->buffer + left), input, fill);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100632
Jens Wiklander32b31802023-10-06 16:59:46 +0200633 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
634 return ret;
635 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100636
Jens Wiklander817466c2018-05-22 13:49:31 +0200637 input += fill;
638 ilen -= fill;
639 left = 0;
640 }
641
Jens Wiklander32b31802023-10-06 16:59:46 +0200642 while (ilen >= SHA256_BLOCK_SIZE) {
643 size_t processed =
644 mbedtls_internal_sha256_process_many(ctx, input, ilen);
645 if (processed < SHA256_BLOCK_SIZE) {
646 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
647 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100648
Jens Wiklander32b31802023-10-06 16:59:46 +0200649 input += processed;
650 ilen -= processed;
Jens Wiklander817466c2018-05-22 13:49:31 +0200651 }
652
Jens Wiklander32b31802023-10-06 16:59:46 +0200653 if (ilen > 0) {
654 memcpy((void *) (ctx->buffer + left), input, ilen);
655 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100656
Jens Wiklander32b31802023-10-06 16:59:46 +0200657 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200658}
659
Jens Wiklander817466c2018-05-22 13:49:31 +0200660/*
661 * SHA-256 final digest
662 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200663int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
664 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +0200665{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200666 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100667 uint32_t used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200668 uint32_t high, low;
Jens Wiklander817466c2018-05-22 13:49:31 +0200669
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100670 /*
671 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
672 */
673 used = ctx->total[0] & 0x3F;
674
675 ctx->buffer[used++] = 0x80;
676
Jens Wiklander32b31802023-10-06 16:59:46 +0200677 if (used <= 56) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100678 /* Enough room for padding + length in current block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200679 memset(ctx->buffer + used, 0, 56 - used);
680 } else {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100681 /* We'll need an extra block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200682 memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100683
Jens Wiklander32b31802023-10-06 16:59:46 +0200684 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
685 return ret;
686 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100687
Jens Wiklander32b31802023-10-06 16:59:46 +0200688 memset(ctx->buffer, 0, 56);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100689 }
690
691 /*
692 * Add message length
693 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200694 high = (ctx->total[0] >> 29)
695 | (ctx->total[1] << 3);
696 low = (ctx->total[0] << 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200697
Jens Wiklander32b31802023-10-06 16:59:46 +0200698 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
699 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Jens Wiklander817466c2018-05-22 13:49:31 +0200700
Jens Wiklander32b31802023-10-06 16:59:46 +0200701 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
702 return ret;
703 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200704
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100705 /*
706 * Output final state
707 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200708 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
709 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
710 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
711 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
712 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
713 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
714 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Jens Wiklander817466c2018-05-22 13:49:31 +0200715
Jens Wiklander32b31802023-10-06 16:59:46 +0200716 int truncated = 0;
717#if defined(MBEDTLS_SHA224_C)
718 truncated = ctx->is224;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100719#endif
Jens Wiklander32b31802023-10-06 16:59:46 +0200720 if (!truncated) {
721 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
722 }
723
724 return 0;
725}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100726
Jens Wiklander817466c2018-05-22 13:49:31 +0200727#endif /* !MBEDTLS_SHA256_ALT */
728
729/*
730 * output = SHA-256( input buffer )
731 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200732int mbedtls_sha256(const unsigned char *input,
733 size_t ilen,
734 unsigned char *output,
735 int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200736{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200737 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200738 mbedtls_sha256_context ctx;
739
Jens Wiklander32b31802023-10-06 16:59:46 +0200740#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
741 if (is224 != 0 && is224 != 1) {
742 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
743 }
744#elif defined(MBEDTLS_SHA256_C)
745 if (is224 != 0) {
746 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
747 }
748#else /* defined MBEDTLS_SHA224_C only */
749 if (is224 == 0) {
750 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
751 }
752#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100753
Jens Wiklander32b31802023-10-06 16:59:46 +0200754 mbedtls_sha256_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100755
Jens Wiklander32b31802023-10-06 16:59:46 +0200756 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100757 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200758 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100759
Jens Wiklander32b31802023-10-06 16:59:46 +0200760 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100761 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200762 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100763
Jens Wiklander32b31802023-10-06 16:59:46 +0200764 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100765 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200766 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100767
768exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200769 mbedtls_sha256_free(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100770
Jens Wiklander32b31802023-10-06 16:59:46 +0200771 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200772}
773
774#if defined(MBEDTLS_SELF_TEST)
775/*
776 * FIPS-180-2 test vectors
777 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200778static const unsigned char sha_test_buf[3][57] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200779{
780 { "abc" },
781 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
782 { "" }
783};
784
Jens Wiklander32b31802023-10-06 16:59:46 +0200785static const size_t sha_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200786{
787 3, 56, 1000
788};
789
Jens Wiklander32b31802023-10-06 16:59:46 +0200790typedef const unsigned char (sha_test_sum_t)[32];
791
792/*
793 * SHA-224 test vectors
794 */
795#if defined(MBEDTLS_SHA224_C)
796static sha_test_sum_t sha224_test_sum[] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200797{
Jens Wiklander817466c2018-05-22 13:49:31 +0200798 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
799 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
800 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
801 0xE3, 0x6C, 0x9D, 0xA7 },
802 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
803 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
804 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
805 0x52, 0x52, 0x25, 0x25 },
806 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
807 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
808 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Jens Wiklander32b31802023-10-06 16:59:46 +0200809 0x4E, 0xE7, 0xAD, 0x67 }
810};
811#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200812
Jens Wiklander32b31802023-10-06 16:59:46 +0200813/*
814 * SHA-256 test vectors
815 */
816#if defined(MBEDTLS_SHA256_C)
817static sha_test_sum_t sha256_test_sum[] =
818{
Jens Wiklander817466c2018-05-22 13:49:31 +0200819 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
820 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
821 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
822 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
823 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
824 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
825 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
826 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
827 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
828 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
829 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
830 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
831};
Jens Wiklander32b31802023-10-06 16:59:46 +0200832#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200833
834/*
835 * Checkup routine
836 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200837static int mbedtls_sha256_common_self_test(int verbose, int is224)
Jens Wiklander817466c2018-05-22 13:49:31 +0200838{
Jens Wiklander32b31802023-10-06 16:59:46 +0200839 int i, buflen, ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200840 unsigned char *buf;
841 unsigned char sha256sum[32];
842 mbedtls_sha256_context ctx;
843
Jens Wiklander32b31802023-10-06 16:59:46 +0200844#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
845 sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
846#elif defined(MBEDTLS_SHA256_C)
847 sha_test_sum_t *sha_test_sum = sha256_test_sum;
848#else
849 sha_test_sum_t *sha_test_sum = sha224_test_sum;
850#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200851
Jens Wiklander32b31802023-10-06 16:59:46 +0200852 buf = mbedtls_calloc(1024, sizeof(unsigned char));
853 if (NULL == buf) {
854 if (verbose != 0) {
855 mbedtls_printf("Buffer allocation failed\n");
856 }
857
858 return 1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200859 }
860
Jens Wiklander32b31802023-10-06 16:59:46 +0200861 mbedtls_sha256_init(&ctx);
Jens Wiklander817466c2018-05-22 13:49:31 +0200862
Jens Wiklander32b31802023-10-06 16:59:46 +0200863 for (i = 0; i < 3; i++) {
864 if (verbose != 0) {
865 mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
866 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200867
Jens Wiklander32b31802023-10-06 16:59:46 +0200868 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100869 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200870 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200871
Jens Wiklander32b31802023-10-06 16:59:46 +0200872 if (i == 2) {
873 memset(buf, 'a', buflen = 1000);
Jens Wiklander817466c2018-05-22 13:49:31 +0200874
Jens Wiklander32b31802023-10-06 16:59:46 +0200875 for (int j = 0; j < 1000; j++) {
876 ret = mbedtls_sha256_update(&ctx, buf, buflen);
877 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100878 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200879 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100880 }
881
Jens Wiklander32b31802023-10-06 16:59:46 +0200882 } else {
883 ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
884 sha_test_buflen[i]);
885 if (ret != 0) {
886 goto fail;
887 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100888 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200889
Jens Wiklander32b31802023-10-06 16:59:46 +0200890 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100891 goto fail;
Jens Wiklander32b31802023-10-06 16:59:46 +0200892 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100893
Jens Wiklander817466c2018-05-22 13:49:31 +0200894
Jens Wiklander32b31802023-10-06 16:59:46 +0200895 if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200896 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100897 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200898 }
899
Jens Wiklander32b31802023-10-06 16:59:46 +0200900 if (verbose != 0) {
901 mbedtls_printf("passed\n");
902 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200903 }
904
Jens Wiklander32b31802023-10-06 16:59:46 +0200905 if (verbose != 0) {
906 mbedtls_printf("\n");
907 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200908
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100909 goto exit;
910
911fail:
Jens Wiklander32b31802023-10-06 16:59:46 +0200912 if (verbose != 0) {
913 mbedtls_printf("failed\n");
914 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100915
Jens Wiklander817466c2018-05-22 13:49:31 +0200916exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200917 mbedtls_sha256_free(&ctx);
918 mbedtls_free(buf);
Jens Wiklander817466c2018-05-22 13:49:31 +0200919
Jens Wiklander32b31802023-10-06 16:59:46 +0200920 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200921}
922
Jens Wiklander32b31802023-10-06 16:59:46 +0200923#if defined(MBEDTLS_SHA256_C)
924int mbedtls_sha256_self_test(int verbose)
925{
926 return mbedtls_sha256_common_self_test(verbose, 0);
927}
928#endif /* MBEDTLS_SHA256_C */
929
930#if defined(MBEDTLS_SHA224_C)
931int mbedtls_sha224_self_test(int verbose)
932{
933 return mbedtls_sha256_common_self_test(verbose, 1);
934}
935#endif /* MBEDTLS_SHA224_C */
936
Jens Wiklander817466c2018-05-22 13:49:31 +0200937#endif /* MBEDTLS_SELF_TEST */
938
Jens Wiklander32b31802023-10-06 16:59:46 +0200939#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */