blob: 4f30e14f894a5e28ab450fd7be26e78a5224d13b [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) || \
39 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
40# 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__)
45 /* Our preferred method of detection is getauxval() */
46# include <sys/auxv.h>
47# endif
48 /* Use SIGILL on Unix, and fall back to it on Linux */
49# 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) || \
54 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
55# 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)
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000068static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000069{
70 return( ( getauxval( AT_HWCAP ) & HWCAP_SHA2 ) ? 1 : 0 );
71}
72#elif defined(__APPLE__)
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000073static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000074{
75 return( 1 );
76}
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
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000082static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000083{
84 return( IsProcessorFeaturePresent( PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE ) ?
85 1 : 0 );
86}
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
92#ifndef asm
93#define asm __asm__
94#endif
95
96static jmp_buf return_from_sigill;
97
98/*
99 * A64 SHA256 support detection via SIGILL
100 */
101static void sigill_handler( int signal )
102{
103 (void) signal;
104 longjmp( return_from_sigill, 1 );
105}
106
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000107static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000108{
109 struct sigaction old_action, new_action;
110
111 sigset_t old_mask;
112 if( sigprocmask( 0, NULL, &old_mask ) )
113 return( 0 );
114
115 sigemptyset( &new_action.sa_mask );
116 new_action.sa_flags = 0;
117 new_action.sa_handler = sigill_handler;
118
119 sigaction( SIGILL, &new_action, &old_action );
120
121 static int ret = 0;
122
123 if( setjmp( return_from_sigill ) == 0 ) /* First return only */
124 {
125 /* If this traps, we will return a second time from setjmp() with 1 */
126 asm( "sha256h q0, q0, v0.4s" : : : "v0" );
127 ret = 1;
128 }
129
130 sigaction( SIGILL, &old_action, NULL );
131 sigprocmask( SIG_SETMASK, &old_mask, NULL );
132
133 return( ret );
134}
135#else
136#warning "No mechanism to detect A64_CRYPTO found, using C code only"
137#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
138#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
139
140#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
141
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200142#if !defined(MBEDTLS_SHA256_ALT)
143
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000144#define SHA256_BLOCK_SIZE 64
145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200147{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200149}
150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200152{
153 if( ctx == NULL )
154 return;
155
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500156 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200157}
158
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200159void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
160 const mbedtls_sha256_context *src )
161{
162 *dst = *src;
163}
164
Paul Bakker5121ce52009-01-03 21:22:43 +0000165/*
166 * SHA-256 context setup
167 */
TRodziewicz26371e42021-06-08 16:45:41 +0200168int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000169{
Valerio Settia3f99592022-12-14 10:56:54 +0100170#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100171 if( is224 != 0 && is224 != 1 )
172 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Valerio Settia3f99592022-12-14 10:56:54 +0100173#elif defined(MBEDTLS_SHA256_C)
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100174 if( is224 != 0 )
175 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Valerio Settia3f99592022-12-14 10:56:54 +0100176#else /* defined MBEDTLS_SHA224_C only */
177 if( is224 == 0 )
178 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200179#endif
180
Paul Bakker5121ce52009-01-03 21:22:43 +0000181 ctx->total[0] = 0;
182 ctx->total[1] = 0;
183
184 if( is224 == 0 )
185 {
Valerio Settia3f99592022-12-14 10:56:54 +0100186#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000187 ctx->state[0] = 0x6A09E667;
188 ctx->state[1] = 0xBB67AE85;
189 ctx->state[2] = 0x3C6EF372;
190 ctx->state[3] = 0xA54FF53A;
191 ctx->state[4] = 0x510E527F;
192 ctx->state[5] = 0x9B05688C;
193 ctx->state[6] = 0x1F83D9AB;
194 ctx->state[7] = 0x5BE0CD19;
Valerio Settia3f99592022-12-14 10:56:54 +0100195#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000196 }
197 else
198 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200199#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000200 ctx->state[0] = 0xC1059ED8;
201 ctx->state[1] = 0x367CD507;
202 ctx->state[2] = 0x3070DD17;
203 ctx->state[3] = 0xF70E5939;
204 ctx->state[4] = 0xFFC00B31;
205 ctx->state[5] = 0x68581511;
206 ctx->state[6] = 0x64F98FA7;
207 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200208#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000209 }
210
Valerio Settia3f99592022-12-14 10:56:54 +0100211#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000212 ctx->is224 = is224;
Valerio Settia3f99592022-12-14 10:56:54 +0100213#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100214
215 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000216}
217
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200219static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000220{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200221 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
222 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
223 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
224 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
225 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
226 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
227 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
228 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
229 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
230 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
231 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
232 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
233 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
234 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
235 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
236 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
237};
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000239#endif
240
241#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
242 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
243
244#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
245# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
246# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
247#endif
248
249static size_t mbedtls_internal_sha256_process_many_a64_crypto(
250 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len )
251{
252 uint32x4_t abcd = vld1q_u32( &ctx->state[0] );
253 uint32x4_t efgh = vld1q_u32( &ctx->state[4] );
254
255 size_t processed = 0;
256
257 for( ;
258 len >= SHA256_BLOCK_SIZE;
259 processed += SHA256_BLOCK_SIZE,
260 msg += SHA256_BLOCK_SIZE,
261 len -= SHA256_BLOCK_SIZE )
262 {
263 uint32x4_t tmp, abcd_prev;
264
265 uint32x4_t abcd_orig = abcd;
266 uint32x4_t efgh_orig = efgh;
267
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000268 uint32x4_t sched0 = (uint32x4_t) vld1q_u8( msg + 16 * 0 );
269 uint32x4_t sched1 = (uint32x4_t) vld1q_u8( msg + 16 * 1 );
270 uint32x4_t sched2 = (uint32x4_t) vld1q_u8( msg + 16 * 2 );
271 uint32x4_t sched3 = (uint32x4_t) vld1q_u8( msg + 16 * 3 );
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000272
273#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
274 /* Untested on BE */
275 sched0 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched0 ) ) );
276 sched1 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched1 ) ) );
277 sched2 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched2 ) ) );
278 sched3 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched3 ) ) );
279#endif
280
281 /* Rounds 0 to 3 */
282 tmp = vaddq_u32( sched0, vld1q_u32( &K[0] ) );
283 abcd_prev = abcd;
284 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
285 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
286
287 /* Rounds 4 to 7 */
288 tmp = vaddq_u32( sched1, vld1q_u32( &K[4] ) );
289 abcd_prev = abcd;
290 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
291 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
292
293 /* Rounds 8 to 11 */
294 tmp = vaddq_u32( sched2, vld1q_u32( &K[8] ) );
295 abcd_prev = abcd;
296 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
297 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
298
299 /* Rounds 12 to 15 */
300 tmp = vaddq_u32( sched3, vld1q_u32( &K[12] ) );
301 abcd_prev = abcd;
302 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
303 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
304
305 for( int t = 16; t < 64; t += 16 )
306 {
307 /* Rounds t to t + 3 */
308 sched0 = vsha256su1q_u32( vsha256su0q_u32( sched0, sched1 ), sched2, sched3 );
309 tmp = vaddq_u32( sched0, vld1q_u32( &K[t] ) );
310 abcd_prev = abcd;
311 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
312 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
313
314 /* Rounds t + 4 to t + 7 */
315 sched1 = vsha256su1q_u32( vsha256su0q_u32( sched1, sched2 ), sched3, sched0 );
316 tmp = vaddq_u32( sched1, vld1q_u32( &K[t + 4] ) );
317 abcd_prev = abcd;
318 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
319 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
320
321 /* Rounds t + 8 to t + 11 */
322 sched2 = vsha256su1q_u32( vsha256su0q_u32( sched2, sched3 ), sched0, sched1 );
323 tmp = vaddq_u32( sched2, vld1q_u32( &K[t + 8] ) );
324 abcd_prev = abcd;
325 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
326 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
327
328 /* Rounds t + 12 to t + 15 */
329 sched3 = vsha256su1q_u32( vsha256su0q_u32( sched3, sched0 ), sched1, sched2 );
330 tmp = vaddq_u32( sched3, vld1q_u32( &K[t + 12] ) );
331 abcd_prev = abcd;
332 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
333 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
334 }
335
336 abcd = vaddq_u32( abcd, abcd_orig );
337 efgh = vaddq_u32( efgh, efgh_orig );
338 }
339
340 vst1q_u32( &ctx->state[0], abcd );
341 vst1q_u32( &ctx->state[4], efgh );
342
343 return( processed );
344}
345
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100346#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
347/*
348 * This function is for internal use only if we are building both C and A64
349 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
350 */
351static
352#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000353int mbedtls_internal_sha256_process_a64_crypto( mbedtls_sha256_context *ctx,
354 const unsigned char data[SHA256_BLOCK_SIZE] )
355{
356 return( ( mbedtls_internal_sha256_process_many_a64_crypto( ctx, data,
357 SHA256_BLOCK_SIZE ) == SHA256_BLOCK_SIZE ) ? 0 : -1 );
358}
359
360#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
361
362
363#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
364#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
365#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
366#endif
367
368
369#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
370 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
371
Hanno Becker1eeca412018-10-15 12:01:35 +0100372#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
373#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
375#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
376#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
377
378#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
379#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
380
Hanno Becker1eeca412018-10-15 12:01:35 +0100381#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
382#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200384#define R(t) \
385 ( \
386 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
387 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100388 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200390#define P(a,b,c,d,e,f,g,h,x,K) \
391 do \
392 { \
393 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
394 local.temp2 = S2(a) + F0((a),(b),(c)); \
395 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100396 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100398#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
399/*
400 * This function is for internal use only if we are building both C and A64
401 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
402 */
403static
404#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000405int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
406 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200407{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200408 struct
409 {
410 uint32_t temp1, temp2, W[64];
411 uint32_t A[8];
412 } local;
413
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200414 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200416 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200417 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200418
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200419#if defined(MBEDTLS_SHA256_SMALLER)
420 for( i = 0; i < 64; i++ )
421 {
422 if( i < 16 )
Joe Subbiani6a506312021-07-07 16:56:29 +0100423 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200424 else
425 R( i );
426
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200427 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
428 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200429
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200430 local.temp1 = local.A[7]; local.A[7] = local.A[6];
431 local.A[6] = local.A[5]; local.A[5] = local.A[4];
432 local.A[4] = local.A[3]; local.A[3] = local.A[2];
433 local.A[2] = local.A[1]; local.A[1] = local.A[0];
434 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200435 }
436#else /* MBEDTLS_SHA256_SMALLER */
437 for( i = 0; i < 16; i++ )
Joe Subbiani6a506312021-07-07 16:56:29 +0100438 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200439
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200440 for( i = 0; i < 16; i += 8 )
441 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200442 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
443 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
444 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
445 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
446 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
447 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
448 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
449 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
450 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
451 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
452 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
453 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
454 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
455 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
456 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
457 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200458 }
459
460 for( i = 16; i < 64; i += 8 )
461 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200462 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
463 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
464 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
465 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
466 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
467 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
468 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
469 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
470 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
471 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
472 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
473 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
474 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
475 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
476 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
477 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200478 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200479#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200480
481 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200482 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100483
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200484 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200485 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100486
487 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488}
Jaeden Amero041039f2018-02-19 15:28:08 +0000489
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000490#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
491
492
493#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
494
495static size_t mbedtls_internal_sha256_process_many_c(
496 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len )
497{
498 size_t processed = 0;
499
500 while( len >= SHA256_BLOCK_SIZE )
501 {
502 if( mbedtls_internal_sha256_process_c( ctx, data ) != 0 )
503 return( 0 );
504
505 data += SHA256_BLOCK_SIZE;
506 len -= SHA256_BLOCK_SIZE;
507
508 processed += SHA256_BLOCK_SIZE;
509 }
510
511 return( processed );
512}
513
514#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
515
516
517#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
518
519static int mbedtls_a64_crypto_sha256_has_support( void )
520{
521 static int done = 0;
522 static int supported = 0;
523
524 if( !done )
525 {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000526 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000527 done = 1;
528 }
529
530 return( supported );
531}
532
533static size_t mbedtls_internal_sha256_process_many( mbedtls_sha256_context *ctx,
534 const uint8_t *msg, size_t len )
535{
536 if( mbedtls_a64_crypto_sha256_has_support() )
537 return( mbedtls_internal_sha256_process_many_a64_crypto( ctx, msg, len ) );
538 else
539 return( mbedtls_internal_sha256_process_many_c( ctx, msg, len ) );
540}
541
542int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
543 const unsigned char data[SHA256_BLOCK_SIZE] )
544{
545 if( mbedtls_a64_crypto_sha256_has_support() )
546 return( mbedtls_internal_sha256_process_a64_crypto( ctx, data ) );
547 else
548 return( mbedtls_internal_sha256_process_c( ctx, data ) );
549}
550
551#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
552
Paul Bakker5121ce52009-01-03 21:22:43 +0000553
554/*
555 * SHA-256 process buffer
556 */
TRodziewicz26371e42021-06-08 16:45:41 +0200557int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100558 const unsigned char *input,
559 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000560{
Janos Follath24eed8d2019-11-22 13:21:35 +0000561 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000562 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000563 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
Brian White12895d12014-04-11 11:29:42 -0400565 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100566 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
568 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000569 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
Paul Bakker5c2364c2012-10-01 14:41:15 +0000571 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 ctx->total[0] &= 0xFFFFFFFF;
573
Paul Bakker5c2364c2012-10-01 14:41:15 +0000574 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000575 ctx->total[1]++;
576
577 if( left && ilen >= fill )
578 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200579 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100580
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100581 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100582 return( ret );
583
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 input += fill;
585 ilen -= fill;
586 left = 0;
587 }
588
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000589 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000590 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000591 size_t processed =
592 mbedtls_internal_sha256_process_many( ctx, input, ilen );
593 if( processed < SHA256_BLOCK_SIZE )
594 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100595
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000596 input += processed;
597 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000598 }
599
600 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200601 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100602
603 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000604}
605
Paul Bakker5121ce52009-01-03 21:22:43 +0000606/*
607 * SHA-256 final digest
608 */
TRodziewicz26371e42021-06-08 16:45:41 +0200609int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200610 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000611{
Janos Follath24eed8d2019-11-22 13:21:35 +0000612 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200613 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000614 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200616 /*
617 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
618 */
619 used = ctx->total[0] & 0x3F;
620
621 ctx->buffer[used++] = 0x80;
622
623 if( used <= 56 )
624 {
625 /* Enough room for padding + length in current block */
626 memset( ctx->buffer + used, 0, 56 - used );
627 }
628 else
629 {
630 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000631 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200632
633 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
634 return( ret );
635
636 memset( ctx->buffer, 0, 56 );
637 }
638
639 /*
640 * Add message length
641 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000642 high = ( ctx->total[0] >> 29 )
643 | ( ctx->total[1] << 3 );
644 low = ( ctx->total[0] << 3 );
645
Joe Subbiani5ecac212021-06-24 13:00:03 +0100646 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
647 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200649 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100650 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100651
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200652 /*
653 * Output final state
654 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100655 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
656 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
657 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
658 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
659 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
660 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
661 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
David Horstmann687262c2022-10-06 17:54:57 +0100663 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200664#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100665 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200666#endif
David Horstmann687262c2022-10-06 17:54:57 +0100667 if( !truncated )
Joe Subbiani5ecac212021-06-24 13:00:03 +0100668 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100669
670 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671}
672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200674
Paul Bakker5121ce52009-01-03 21:22:43 +0000675/*
676 * output = SHA-256( input buffer )
677 */
TRodziewicz26371e42021-06-08 16:45:41 +0200678int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100679 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200680 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100681 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000682{
Janos Follath24eed8d2019-11-22 13:21:35 +0000683 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000685
Valerio Settia3f99592022-12-14 10:56:54 +0100686#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100687 if( is224 != 0 && is224 != 1 )
688 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Valerio Settia3f99592022-12-14 10:56:54 +0100689#elif defined(MBEDTLS_SHA256_C)
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100690 if( is224 != 0 )
691 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Valerio Settia3f99592022-12-14 10:56:54 +0100692#else /* defined MBEDTLS_SHA224_C only */
693 if( is224 == 0 )
694 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200695#endif
696
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100698
TRodziewicz26371e42021-06-08 16:45:41 +0200699 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100700 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100701
TRodziewicz26371e42021-06-08 16:45:41 +0200702 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100703 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100704
TRodziewicz26371e42021-06-08 16:45:41 +0200705 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100706 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100707
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100708exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100710
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100711 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000712}
713
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000715/*
716 * FIPS-180-2 test vectors
717 */
Valerio Settia3f99592022-12-14 10:56:54 +0100718static const unsigned char sha_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000719{
720 { "abc" },
721 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
722 { "" }
723};
724
Valerio Settia3f99592022-12-14 10:56:54 +0100725static const size_t sha_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000726{
727 3, 56, 1000
728};
729
Valerio Settia3f99592022-12-14 10:56:54 +0100730typedef const unsigned char (sha_test_sum_t)[32];
731
732/*
733 * SHA-224 test vectors
734 */
735#if defined(MBEDTLS_SHA224_C)
736static sha_test_sum_t sha224_test_sum[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000737{
Paul Bakker5121ce52009-01-03 21:22:43 +0000738 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
739 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
740 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
741 0xE3, 0x6C, 0x9D, 0xA7 },
742 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
743 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
744 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
745 0x52, 0x52, 0x25, 0x25 },
746 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
747 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
748 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
Valerio Settia3f99592022-12-14 10:56:54 +0100749 0x4E, 0xE7, 0xAD, 0x67 }
750};
751#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000752
Valerio Settia3f99592022-12-14 10:56:54 +0100753/*
754 * SHA-256 test vectors
755 */
756#if defined(MBEDTLS_SHA256_C)
757static sha_test_sum_t sha256_test_sum[] =
758{
Paul Bakker5121ce52009-01-03 21:22:43 +0000759 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
760 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
761 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
762 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
763 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
764 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
765 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
766 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
767 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
768 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
769 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
770 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
771};
Valerio Settia3f99592022-12-14 10:56:54 +0100772#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000773
774/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000775 * Checkup routine
776 */
Valerio Settia3f99592022-12-14 10:56:54 +0100777static int mbedtls_sha256_common_self_test( int verbose, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000778{
Valerio Settia3f99592022-12-14 10:56:54 +0100779 int i, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500780 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200781 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000783
Valerio Settia3f99592022-12-14 10:56:54 +0100784 sha_test_sum_t* sha_test_sum;
785
786 sha_test_sum =
787#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
788 ( is224 ) ? sha224_test_sum : sha256_test_sum;
789#elif defined(MBEDTLS_SHA256_C)
790 sha256_test_sum;
791#else
792 sha224_test_sum;
793#endif
794
Russ Butlerbb83b422016-10-12 17:36:50 -0500795 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
796 if( NULL == buf )
797 {
798 if( verbose != 0 )
799 mbedtls_printf( "Buffer allocation failed\n" );
800
801 return( 1 );
802 }
803
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200804 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200805
Valerio Settia3f99592022-12-14 10:56:54 +0100806 for( i = 0; i < 3; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000807 {
Paul Bakker5121ce52009-01-03 21:22:43 +0000808 if( verbose != 0 )
Valerio Settia3f99592022-12-14 10:56:54 +0100809 mbedtls_printf( " SHA-%d test #%d: ", 256 - is224 * 32, i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000810
Valerio Settia3f99592022-12-14 10:56:54 +0100811 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100812 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
Valerio Settia3f99592022-12-14 10:56:54 +0100814 if( i == 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000815 {
816 memset( buf, 'a', buflen = 1000 );
817
Valerio Settia3f99592022-12-14 10:56:54 +0100818 for( int j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100819 {
TRodziewicz26371e42021-06-08 16:45:41 +0200820 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100821 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100822 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100823 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100824
Paul Bakker5121ce52009-01-03 21:22:43 +0000825 }
826 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100827 {
Valerio Settia3f99592022-12-14 10:56:54 +0100828 ret = mbedtls_sha256_update( &ctx, sha_test_buf[i],
829 sha_test_buflen[i] );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100830 if( ret != 0 )
831 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100832 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000833
TRodziewicz26371e42021-06-08 16:45:41 +0200834 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100835 goto fail;
836
Paul Bakker5121ce52009-01-03 21:22:43 +0000837
Valerio Settia3f99592022-12-14 10:56:54 +0100838 if( memcmp( sha256sum, sha_test_sum[i], 32 - is224 * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100839 {
840 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100841 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100842 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000843
844 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000846 }
847
848 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000850
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100851 goto exit;
852
853fail:
854 if( verbose != 0 )
855 mbedtls_printf( "failed\n" );
856
Paul Bakker5b4af392014-06-26 12:09:34 +0200857exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500859 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200860
861 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000862}
863
Valerio Settia3f99592022-12-14 10:56:54 +0100864#if defined(MBEDTLS_SHA256_C)
865int mbedtls_sha256_self_test( int verbose )
866{
867 return mbedtls_sha256_common_self_test( verbose, 0 );
868}
869#endif /* MBEDTLS_SHA256_C */
870
871#if defined(MBEDTLS_SHA224_C)
872int mbedtls_sha224_self_test( int verbose )
873{
874 return mbedtls_sha256_common_self_test( verbose, 1 );
875}
876#endif /* MBEDTLS_SHA224_C */
877
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000879
Valerio Settia3f99592022-12-14 10:56:54 +0100880#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */