blob: 6596a3dfc58e2756cf4570de9c146cd154fa790d [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_SHA256_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
Hanno Becker2f6de422018-12-20 10:22:32 +0000142#define SHA256_VALIDATE_RET(cond) \
143 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
144#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
145
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200146#if !defined(MBEDTLS_SHA256_ALT)
147
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000148#define SHA256_BLOCK_SIZE 64
149
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200151{
Hanno Becker8d215e72018-12-18 17:53:21 +0000152 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000153
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200155}
156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200158{
159 if( ctx == NULL )
160 return;
161
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500162 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200163}
164
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200165void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
166 const mbedtls_sha256_context *src )
167{
Hanno Becker8d215e72018-12-18 17:53:21 +0000168 SHA256_VALIDATE( dst != NULL );
169 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000170
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200171 *dst = *src;
172}
173
Paul Bakker5121ce52009-01-03 21:22:43 +0000174/*
175 * SHA-256 context setup
176 */
TRodziewicz26371e42021-06-08 16:45:41 +0200177int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000178{
Hanno Becker8d215e72018-12-18 17:53:21 +0000179 SHA256_VALIDATE_RET( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000180
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200181#if defined(MBEDTLS_SHA224_C)
182 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
183#else
184 SHA256_VALIDATE_RET( is224 == 0 );
185#endif
186
Paul Bakker5121ce52009-01-03 21:22:43 +0000187 ctx->total[0] = 0;
188 ctx->total[1] = 0;
189
190 if( is224 == 0 )
191 {
192 /* SHA-256 */
193 ctx->state[0] = 0x6A09E667;
194 ctx->state[1] = 0xBB67AE85;
195 ctx->state[2] = 0x3C6EF372;
196 ctx->state[3] = 0xA54FF53A;
197 ctx->state[4] = 0x510E527F;
198 ctx->state[5] = 0x9B05688C;
199 ctx->state[6] = 0x1F83D9AB;
200 ctx->state[7] = 0x5BE0CD19;
201 }
202 else
203 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200204#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000205 /* SHA-224 */
206 ctx->state[0] = 0xC1059ED8;
207 ctx->state[1] = 0x367CD507;
208 ctx->state[2] = 0x3070DD17;
209 ctx->state[3] = 0xF70E5939;
210 ctx->state[4] = 0xFFC00B31;
211 ctx->state[5] = 0x68581511;
212 ctx->state[6] = 0x64F98FA7;
213 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200214#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 }
216
217 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100218
219 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000220}
221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200223static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000224{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200225 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
226 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
227 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
228 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
229 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
230 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
231 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
232 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
233 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
234 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
235 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
236 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
237 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
238 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
239 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
240 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
241};
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000243#endif
244
245#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
246 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
247
248#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
249# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
250# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
251#endif
252
253static size_t mbedtls_internal_sha256_process_many_a64_crypto(
254 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len )
255{
256 uint32x4_t abcd = vld1q_u32( &ctx->state[0] );
257 uint32x4_t efgh = vld1q_u32( &ctx->state[4] );
258
259 size_t processed = 0;
260
261 for( ;
262 len >= SHA256_BLOCK_SIZE;
263 processed += SHA256_BLOCK_SIZE,
264 msg += SHA256_BLOCK_SIZE,
265 len -= SHA256_BLOCK_SIZE )
266 {
267 uint32x4_t tmp, abcd_prev;
268
269 uint32x4_t abcd_orig = abcd;
270 uint32x4_t efgh_orig = efgh;
271
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000272 uint32x4_t sched0 = (uint32x4_t) vld1q_u8( msg + 16 * 0 );
273 uint32x4_t sched1 = (uint32x4_t) vld1q_u8( msg + 16 * 1 );
274 uint32x4_t sched2 = (uint32x4_t) vld1q_u8( msg + 16 * 2 );
275 uint32x4_t sched3 = (uint32x4_t) vld1q_u8( msg + 16 * 3 );
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000276
277#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
278 /* Untested on BE */
279 sched0 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched0 ) ) );
280 sched1 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched1 ) ) );
281 sched2 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched2 ) ) );
282 sched3 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched3 ) ) );
283#endif
284
285 /* Rounds 0 to 3 */
286 tmp = vaddq_u32( sched0, vld1q_u32( &K[0] ) );
287 abcd_prev = abcd;
288 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
289 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
290
291 /* Rounds 4 to 7 */
292 tmp = vaddq_u32( sched1, vld1q_u32( &K[4] ) );
293 abcd_prev = abcd;
294 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
295 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
296
297 /* Rounds 8 to 11 */
298 tmp = vaddq_u32( sched2, vld1q_u32( &K[8] ) );
299 abcd_prev = abcd;
300 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
301 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
302
303 /* Rounds 12 to 15 */
304 tmp = vaddq_u32( sched3, vld1q_u32( &K[12] ) );
305 abcd_prev = abcd;
306 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
307 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
308
309 for( int t = 16; t < 64; t += 16 )
310 {
311 /* Rounds t to t + 3 */
312 sched0 = vsha256su1q_u32( vsha256su0q_u32( sched0, sched1 ), sched2, sched3 );
313 tmp = vaddq_u32( sched0, vld1q_u32( &K[t] ) );
314 abcd_prev = abcd;
315 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
316 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
317
318 /* Rounds t + 4 to t + 7 */
319 sched1 = vsha256su1q_u32( vsha256su0q_u32( sched1, sched2 ), sched3, sched0 );
320 tmp = vaddq_u32( sched1, vld1q_u32( &K[t + 4] ) );
321 abcd_prev = abcd;
322 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
323 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
324
325 /* Rounds t + 8 to t + 11 */
326 sched2 = vsha256su1q_u32( vsha256su0q_u32( sched2, sched3 ), sched0, sched1 );
327 tmp = vaddq_u32( sched2, vld1q_u32( &K[t + 8] ) );
328 abcd_prev = abcd;
329 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
330 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
331
332 /* Rounds t + 12 to t + 15 */
333 sched3 = vsha256su1q_u32( vsha256su0q_u32( sched3, sched0 ), sched1, sched2 );
334 tmp = vaddq_u32( sched3, vld1q_u32( &K[t + 12] ) );
335 abcd_prev = abcd;
336 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
337 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
338 }
339
340 abcd = vaddq_u32( abcd, abcd_orig );
341 efgh = vaddq_u32( efgh, efgh_orig );
342 }
343
344 vst1q_u32( &ctx->state[0], abcd );
345 vst1q_u32( &ctx->state[4], efgh );
346
347 return( processed );
348}
349
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100350#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
351/*
352 * This function is for internal use only if we are building both C and A64
353 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
354 */
355static
356#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000357int mbedtls_internal_sha256_process_a64_crypto( mbedtls_sha256_context *ctx,
358 const unsigned char data[SHA256_BLOCK_SIZE] )
359{
360 return( ( mbedtls_internal_sha256_process_many_a64_crypto( ctx, data,
361 SHA256_BLOCK_SIZE ) == SHA256_BLOCK_SIZE ) ? 0 : -1 );
362}
363
364#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
365
366
367#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
368#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
369#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
370#endif
371
372
373#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
374 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
375
Hanno Becker1eeca412018-10-15 12:01:35 +0100376#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
377#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
379#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
380#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
381
382#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
383#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
384
Hanno Becker1eeca412018-10-15 12:01:35 +0100385#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
386#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200388#define R(t) \
389 ( \
390 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
391 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100392 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000393
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200394#define P(a,b,c,d,e,f,g,h,x,K) \
395 do \
396 { \
397 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
398 local.temp2 = S2(a) + F0((a),(b),(c)); \
399 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100400 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100402#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
403/*
404 * This function is for internal use only if we are building both C and A64
405 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
406 */
407static
408#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000409int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
410 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200411{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200412 struct
413 {
414 uint32_t temp1, temp2, W[64];
415 uint32_t A[8];
416 } local;
417
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200418 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
Hanno Becker8d215e72018-12-18 17:53:21 +0000420 SHA256_VALIDATE_RET( ctx != NULL );
421 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000422
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200423 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200424 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200425
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200426#if defined(MBEDTLS_SHA256_SMALLER)
427 for( i = 0; i < 64; i++ )
428 {
429 if( i < 16 )
Joe Subbiani6a506312021-07-07 16:56:29 +0100430 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200431 else
432 R( i );
433
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200434 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
435 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200436
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200437 local.temp1 = local.A[7]; local.A[7] = local.A[6];
438 local.A[6] = local.A[5]; local.A[5] = local.A[4];
439 local.A[4] = local.A[3]; local.A[3] = local.A[2];
440 local.A[2] = local.A[1]; local.A[1] = local.A[0];
441 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200442 }
443#else /* MBEDTLS_SHA256_SMALLER */
444 for( i = 0; i < 16; i++ )
Joe Subbiani6a506312021-07-07 16:56:29 +0100445 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200446
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200447 for( i = 0; i < 16; i += 8 )
448 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200449 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
450 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
451 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
452 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
453 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
454 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
455 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
456 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
457 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
458 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
459 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
460 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
461 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
462 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
463 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
464 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 +0200465 }
466
467 for( i = 16; i < 64; i += 8 )
468 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200469 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
470 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
471 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
472 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
473 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
474 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
475 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
476 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
477 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
478 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
479 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
480 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
481 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
482 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
483 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
484 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200485 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200486#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200487
488 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200489 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100490
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200491 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200492 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100493
494 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495}
Jaeden Amero041039f2018-02-19 15:28:08 +0000496
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000497#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
498
499
500#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
501
502static size_t mbedtls_internal_sha256_process_many_c(
503 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len )
504{
505 size_t processed = 0;
506
507 while( len >= SHA256_BLOCK_SIZE )
508 {
509 if( mbedtls_internal_sha256_process_c( ctx, data ) != 0 )
510 return( 0 );
511
512 data += SHA256_BLOCK_SIZE;
513 len -= SHA256_BLOCK_SIZE;
514
515 processed += SHA256_BLOCK_SIZE;
516 }
517
518 return( processed );
519}
520
521#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
522
523
524#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
525
526static int mbedtls_a64_crypto_sha256_has_support( void )
527{
528 static int done = 0;
529 static int supported = 0;
530
531 if( !done )
532 {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000533 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000534 done = 1;
535 }
536
537 return( supported );
538}
539
540static size_t mbedtls_internal_sha256_process_many( mbedtls_sha256_context *ctx,
541 const uint8_t *msg, size_t len )
542{
543 if( mbedtls_a64_crypto_sha256_has_support() )
544 return( mbedtls_internal_sha256_process_many_a64_crypto( ctx, msg, len ) );
545 else
546 return( mbedtls_internal_sha256_process_many_c( ctx, msg, len ) );
547}
548
549int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
550 const unsigned char data[SHA256_BLOCK_SIZE] )
551{
552 if( mbedtls_a64_crypto_sha256_has_support() )
553 return( mbedtls_internal_sha256_process_a64_crypto( ctx, data ) );
554 else
555 return( mbedtls_internal_sha256_process_c( ctx, data ) );
556}
557
558#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
559
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561/*
562 * SHA-256 process buffer
563 */
TRodziewicz26371e42021-06-08 16:45:41 +0200564int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100565 const unsigned char *input,
566 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000567{
Janos Follath24eed8d2019-11-22 13:21:35 +0000568 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000569 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000570 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
Hanno Becker8d215e72018-12-18 17:53:21 +0000572 SHA256_VALIDATE_RET( ctx != NULL );
573 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000574
Brian White12895d12014-04-11 11:29:42 -0400575 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100576 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
578 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000579 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Paul Bakker5c2364c2012-10-01 14:41:15 +0000581 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 ctx->total[0] &= 0xFFFFFFFF;
583
Paul Bakker5c2364c2012-10-01 14:41:15 +0000584 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000585 ctx->total[1]++;
586
587 if( left && ilen >= fill )
588 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200589 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100590
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100591 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100592 return( ret );
593
Paul Bakker5121ce52009-01-03 21:22:43 +0000594 input += fill;
595 ilen -= fill;
596 left = 0;
597 }
598
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000599 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000600 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000601 size_t processed =
602 mbedtls_internal_sha256_process_many( ctx, input, ilen );
603 if( processed < SHA256_BLOCK_SIZE )
604 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100605
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000606 input += processed;
607 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
609
610 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200611 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100612
613 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000614}
615
Paul Bakker5121ce52009-01-03 21:22:43 +0000616/*
617 * SHA-256 final digest
618 */
TRodziewicz26371e42021-06-08 16:45:41 +0200619int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200620 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000621{
Janos Follath24eed8d2019-11-22 13:21:35 +0000622 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200623 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000624 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
Hanno Becker8d215e72018-12-18 17:53:21 +0000626 SHA256_VALIDATE_RET( ctx != NULL );
627 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000628
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200629 /*
630 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
631 */
632 used = ctx->total[0] & 0x3F;
633
634 ctx->buffer[used++] = 0x80;
635
636 if( used <= 56 )
637 {
638 /* Enough room for padding + length in current block */
639 memset( ctx->buffer + used, 0, 56 - used );
640 }
641 else
642 {
643 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000644 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200645
646 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
647 return( ret );
648
649 memset( ctx->buffer, 0, 56 );
650 }
651
652 /*
653 * Add message length
654 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000655 high = ( ctx->total[0] >> 29 )
656 | ( ctx->total[1] << 3 );
657 low = ( ctx->total[0] << 3 );
658
Joe Subbiani5ecac212021-06-24 13:00:03 +0100659 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
660 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200662 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100663 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100664
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200665 /*
666 * Output final state
667 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100668 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
669 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
670 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
671 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
672 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
673 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
674 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200676#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000677 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200678#endif
Joe Subbiani5ecac212021-06-24 13:00:03 +0100679 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100680
681 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000682}
683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200685
Paul Bakker5121ce52009-01-03 21:22:43 +0000686/*
687 * output = SHA-256( input buffer )
688 */
TRodziewicz26371e42021-06-08 16:45:41 +0200689int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100690 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200691 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100692 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000693{
Janos Follath24eed8d2019-11-22 13:21:35 +0000694 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200697#if defined(MBEDTLS_SHA224_C)
Hanno Becker8d215e72018-12-18 17:53:21 +0000698 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200699#else
700 SHA256_VALIDATE_RET( is224 == 0 );
701#endif
702
Hanno Becker8d215e72018-12-18 17:53:21 +0000703 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
704 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000705
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100707
TRodziewicz26371e42021-06-08 16:45:41 +0200708 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100709 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100710
TRodziewicz26371e42021-06-08 16:45:41 +0200711 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100712 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100713
TRodziewicz26371e42021-06-08 16:45:41 +0200714 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100715 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100716
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100717exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200718 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100719
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100720 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000721}
722
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000724/*
725 * FIPS-180-2 test vectors
726 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000727static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000728{
729 { "abc" },
730 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
731 { "" }
732};
733
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100734static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000735{
736 3, 56, 1000
737};
738
Paul Bakker9e36f042013-06-30 14:34:05 +0200739static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000740{
741 /*
742 * SHA-224 test vectors
743 */
744 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
745 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
746 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
747 0xE3, 0x6C, 0x9D, 0xA7 },
748 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
749 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
750 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
751 0x52, 0x52, 0x25, 0x25 },
752 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
753 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
754 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
755 0x4E, 0xE7, 0xAD, 0x67 },
756
757 /*
758 * SHA-256 test vectors
759 */
760 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
761 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
762 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
763 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
764 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
765 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
766 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
767 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
768 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
769 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
770 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
771 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
772};
773
774/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000775 * Checkup routine
776 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000778{
Paul Bakker5b4af392014-06-26 12:09:34 +0200779 int i, j, k, 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
Russ Butlerbb83b422016-10-12 17:36:50 -0500784 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
785 if( NULL == buf )
786 {
787 if( verbose != 0 )
788 mbedtls_printf( "Buffer allocation failed\n" );
789
790 return( 1 );
791 }
792
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200794
Paul Bakker5121ce52009-01-03 21:22:43 +0000795 for( i = 0; i < 6; i++ )
796 {
797 j = i % 3;
798 k = i < 3;
799
800 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000802
TRodziewicz26371e42021-06-08 16:45:41 +0200803 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100804 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000805
806 if( j == 2 )
807 {
808 memset( buf, 'a', buflen = 1000 );
809
810 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100811 {
TRodziewicz26371e42021-06-08 16:45:41 +0200812 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100813 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100814 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100815 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100816
Paul Bakker5121ce52009-01-03 21:22:43 +0000817 }
818 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100819 {
TRodziewicz26371e42021-06-08 16:45:41 +0200820 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100821 sha256_test_buflen[j] );
822 if( ret != 0 )
823 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100824 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
TRodziewicz26371e42021-06-08 16:45:41 +0200826 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100827 goto fail;
828
Paul Bakker5121ce52009-01-03 21:22:43 +0000829
Paul Bakker9e36f042013-06-30 14:34:05 +0200830 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100831 {
832 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100833 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100834 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000835
836 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000838 }
839
840 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000842
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100843 goto exit;
844
845fail:
846 if( verbose != 0 )
847 mbedtls_printf( "failed\n" );
848
Paul Bakker5b4af392014-06-26 12:09:34 +0200849exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500851 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200852
853 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000854}
855
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000857
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858#endif /* MBEDTLS_SHA256_C */