blob: a20a3e96d0c6721c28490640e7e9783b460d9cb8 [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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_SELF_TEST)
36#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010038#else
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050040#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050042#define mbedtls_calloc calloc
43#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#endif /* MBEDTLS_PLATFORM_C */
45#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000047#if defined(__aarch64__)
48# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
49 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
50# include <arm_neon.h>
51# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000052# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
53# if defined(__unix__)
54# if defined(__linux__)
55 /* Our preferred method of detection is getauxval() */
56# include <sys/auxv.h>
57# endif
58 /* Use SIGILL on Unix, and fall back to it on Linux */
59# include <signal.h>
60# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000061# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000062#elif defined(_M_ARM64)
63# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
64 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
65# include <arm64_neon.h>
66# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000067#else
68# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
69# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
70#endif
71
72#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
73/*
74 * Capability detection code comes early, so we can disable
75 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
76 */
77#if defined(HWCAP_SHA2)
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000078static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000079{
80 return( ( getauxval( AT_HWCAP ) & HWCAP_SHA2 ) ? 1 : 0 );
81}
82#elif defined(__APPLE__)
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000083static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000084{
85 return( 1 );
86}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000087#elif defined(_M_ARM64)
88#define WIN32_LEAN_AND_MEAN
89#include <Windows.h>
90#include <processthreadsapi.h>
91
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000092static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000093{
94 return( IsProcessorFeaturePresent( PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE ) ?
95 1 : 0 );
96}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000097#elif defined(__unix__) && defined(SIG_SETMASK)
98/* Detection with SIGILL, setjmp() and longjmp() */
99#include <signal.h>
100#include <setjmp.h>
101
102#ifndef asm
103#define asm __asm__
104#endif
105
106static jmp_buf return_from_sigill;
107
108/*
109 * A64 SHA256 support detection via SIGILL
110 */
111static void sigill_handler( int signal )
112{
113 (void) signal;
114 longjmp( return_from_sigill, 1 );
115}
116
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000117static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000118{
119 struct sigaction old_action, new_action;
120
121 sigset_t old_mask;
122 if( sigprocmask( 0, NULL, &old_mask ) )
123 return( 0 );
124
125 sigemptyset( &new_action.sa_mask );
126 new_action.sa_flags = 0;
127 new_action.sa_handler = sigill_handler;
128
129 sigaction( SIGILL, &new_action, &old_action );
130
131 static int ret = 0;
132
133 if( setjmp( return_from_sigill ) == 0 ) /* First return only */
134 {
135 /* If this traps, we will return a second time from setjmp() with 1 */
136 asm( "sha256h q0, q0, v0.4s" : : : "v0" );
137 ret = 1;
138 }
139
140 sigaction( SIGILL, &old_action, NULL );
141 sigprocmask( SIG_SETMASK, &old_mask, NULL );
142
143 return( ret );
144}
145#else
146#warning "No mechanism to detect A64_CRYPTO found, using C code only"
147#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
148#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
149
150#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
151
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200152#if !defined(MBEDTLS_SHA256_ALT)
153
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000154#define SHA256_BLOCK_SIZE 64
155
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200157{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200159}
160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200162{
163 if( ctx == NULL )
164 return;
165
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500166 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200167}
168
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200169void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
170 const mbedtls_sha256_context *src )
171{
172 *dst = *src;
173}
174
Paul Bakker5121ce52009-01-03 21:22:43 +0000175/*
176 * SHA-256 context setup
177 */
TRodziewicz26371e42021-06-08 16:45:41 +0200178int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000179{
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200180#if defined(MBEDTLS_SHA224_C)
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100181 if( is224 != 0 && is224 != 1 )
182 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200183#else
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100184 if( is224 != 0 )
185 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200186#endif
187
Paul Bakker5121ce52009-01-03 21:22:43 +0000188 ctx->total[0] = 0;
189 ctx->total[1] = 0;
190
191 if( is224 == 0 )
192 {
193 /* SHA-256 */
194 ctx->state[0] = 0x6A09E667;
195 ctx->state[1] = 0xBB67AE85;
196 ctx->state[2] = 0x3C6EF372;
197 ctx->state[3] = 0xA54FF53A;
198 ctx->state[4] = 0x510E527F;
199 ctx->state[5] = 0x9B05688C;
200 ctx->state[6] = 0x1F83D9AB;
201 ctx->state[7] = 0x5BE0CD19;
202 }
203 else
204 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200205#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000206 /* SHA-224 */
207 ctx->state[0] = 0xC1059ED8;
208 ctx->state[1] = 0x367CD507;
209 ctx->state[2] = 0x3070DD17;
210 ctx->state[3] = 0xF70E5939;
211 ctx->state[4] = 0xFFC00B31;
212 ctx->state[5] = 0x68581511;
213 ctx->state[6] = 0x64F98FA7;
214 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200215#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000216 }
217
218 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100219
220 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000221}
222
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200224static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000225{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200226 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
227 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
228 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
229 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
230 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
231 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
232 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
233 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
234 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
235 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
236 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
237 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
238 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
239 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
240 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
241 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
242};
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000244#endif
245
246#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
247 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
248
249#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
250# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
251# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
252#endif
253
254static size_t mbedtls_internal_sha256_process_many_a64_crypto(
255 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len )
256{
257 uint32x4_t abcd = vld1q_u32( &ctx->state[0] );
258 uint32x4_t efgh = vld1q_u32( &ctx->state[4] );
259
260 size_t processed = 0;
261
262 for( ;
263 len >= SHA256_BLOCK_SIZE;
264 processed += SHA256_BLOCK_SIZE,
265 msg += SHA256_BLOCK_SIZE,
266 len -= SHA256_BLOCK_SIZE )
267 {
268 uint32x4_t tmp, abcd_prev;
269
270 uint32x4_t abcd_orig = abcd;
271 uint32x4_t efgh_orig = efgh;
272
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000273 uint32x4_t sched0 = (uint32x4_t) vld1q_u8( msg + 16 * 0 );
274 uint32x4_t sched1 = (uint32x4_t) vld1q_u8( msg + 16 * 1 );
275 uint32x4_t sched2 = (uint32x4_t) vld1q_u8( msg + 16 * 2 );
276 uint32x4_t sched3 = (uint32x4_t) vld1q_u8( msg + 16 * 3 );
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000277
278#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
279 /* Untested on BE */
280 sched0 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched0 ) ) );
281 sched1 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched1 ) ) );
282 sched2 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched2 ) ) );
283 sched3 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched3 ) ) );
284#endif
285
286 /* Rounds 0 to 3 */
287 tmp = vaddq_u32( sched0, vld1q_u32( &K[0] ) );
288 abcd_prev = abcd;
289 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
290 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
291
292 /* Rounds 4 to 7 */
293 tmp = vaddq_u32( sched1, vld1q_u32( &K[4] ) );
294 abcd_prev = abcd;
295 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
296 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
297
298 /* Rounds 8 to 11 */
299 tmp = vaddq_u32( sched2, vld1q_u32( &K[8] ) );
300 abcd_prev = abcd;
301 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
302 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
303
304 /* Rounds 12 to 15 */
305 tmp = vaddq_u32( sched3, vld1q_u32( &K[12] ) );
306 abcd_prev = abcd;
307 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
308 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
309
310 for( int t = 16; t < 64; t += 16 )
311 {
312 /* Rounds t to t + 3 */
313 sched0 = vsha256su1q_u32( vsha256su0q_u32( sched0, sched1 ), sched2, sched3 );
314 tmp = vaddq_u32( sched0, vld1q_u32( &K[t] ) );
315 abcd_prev = abcd;
316 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
317 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
318
319 /* Rounds t + 4 to t + 7 */
320 sched1 = vsha256su1q_u32( vsha256su0q_u32( sched1, sched2 ), sched3, sched0 );
321 tmp = vaddq_u32( sched1, vld1q_u32( &K[t + 4] ) );
322 abcd_prev = abcd;
323 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
324 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
325
326 /* Rounds t + 8 to t + 11 */
327 sched2 = vsha256su1q_u32( vsha256su0q_u32( sched2, sched3 ), sched0, sched1 );
328 tmp = vaddq_u32( sched2, vld1q_u32( &K[t + 8] ) );
329 abcd_prev = abcd;
330 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
331 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
332
333 /* Rounds t + 12 to t + 15 */
334 sched3 = vsha256su1q_u32( vsha256su0q_u32( sched3, sched0 ), sched1, sched2 );
335 tmp = vaddq_u32( sched3, vld1q_u32( &K[t + 12] ) );
336 abcd_prev = abcd;
337 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
338 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
339 }
340
341 abcd = vaddq_u32( abcd, abcd_orig );
342 efgh = vaddq_u32( efgh, efgh_orig );
343 }
344
345 vst1q_u32( &ctx->state[0], abcd );
346 vst1q_u32( &ctx->state[4], efgh );
347
348 return( processed );
349}
350
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100351#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
352/*
353 * This function is for internal use only if we are building both C and A64
354 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
355 */
356static
357#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000358int mbedtls_internal_sha256_process_a64_crypto( mbedtls_sha256_context *ctx,
359 const unsigned char data[SHA256_BLOCK_SIZE] )
360{
361 return( ( mbedtls_internal_sha256_process_many_a64_crypto( ctx, data,
362 SHA256_BLOCK_SIZE ) == SHA256_BLOCK_SIZE ) ? 0 : -1 );
363}
364
365#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
366
367
368#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
369#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
370#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
371#endif
372
373
374#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
375 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
376
Hanno Becker1eeca412018-10-15 12:01:35 +0100377#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
378#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
380#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
381#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
382
383#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
384#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
385
Hanno Becker1eeca412018-10-15 12:01:35 +0100386#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
387#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200389#define R(t) \
390 ( \
391 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
392 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100393 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000394
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200395#define P(a,b,c,d,e,f,g,h,x,K) \
396 do \
397 { \
398 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
399 local.temp2 = S2(a) + F0((a),(b),(c)); \
400 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100401 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100403#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
404/*
405 * This function is for internal use only if we are building both C and A64
406 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
407 */
408static
409#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000410int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
411 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200412{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200413 struct
414 {
415 uint32_t temp1, temp2, W[64];
416 uint32_t A[8];
417 } local;
418
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200419 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200421 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200422 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200423
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200424#if defined(MBEDTLS_SHA256_SMALLER)
425 for( i = 0; i < 64; i++ )
426 {
427 if( i < 16 )
Joe Subbiani6a506312021-07-07 16:56:29 +0100428 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200429 else
430 R( i );
431
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200432 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
433 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200434
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200435 local.temp1 = local.A[7]; local.A[7] = local.A[6];
436 local.A[6] = local.A[5]; local.A[5] = local.A[4];
437 local.A[4] = local.A[3]; local.A[3] = local.A[2];
438 local.A[2] = local.A[1]; local.A[1] = local.A[0];
439 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200440 }
441#else /* MBEDTLS_SHA256_SMALLER */
442 for( i = 0; i < 16; i++ )
Joe Subbiani6a506312021-07-07 16:56:29 +0100443 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200444
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200445 for( i = 0; i < 16; i += 8 )
446 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200447 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
448 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
449 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
450 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
451 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
452 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
453 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
454 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
455 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
456 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
457 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
458 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
459 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
460 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
461 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
462 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 +0200463 }
464
465 for( i = 16; i < 64; i += 8 )
466 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200467 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
468 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
469 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
470 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
471 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
472 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
473 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
474 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
475 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
476 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
477 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
478 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
479 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
480 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
481 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
482 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200483 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200484#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200485
486 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200487 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100488
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200489 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200490 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100491
492 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000493}
Jaeden Amero041039f2018-02-19 15:28:08 +0000494
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000495#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
496
497
498#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
499
500static size_t mbedtls_internal_sha256_process_many_c(
501 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len )
502{
503 size_t processed = 0;
504
505 while( len >= SHA256_BLOCK_SIZE )
506 {
507 if( mbedtls_internal_sha256_process_c( ctx, data ) != 0 )
508 return( 0 );
509
510 data += SHA256_BLOCK_SIZE;
511 len -= SHA256_BLOCK_SIZE;
512
513 processed += SHA256_BLOCK_SIZE;
514 }
515
516 return( processed );
517}
518
519#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
520
521
522#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
523
524static int mbedtls_a64_crypto_sha256_has_support( void )
525{
526 static int done = 0;
527 static int supported = 0;
528
529 if( !done )
530 {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000531 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000532 done = 1;
533 }
534
535 return( supported );
536}
537
538static size_t mbedtls_internal_sha256_process_many( mbedtls_sha256_context *ctx,
539 const uint8_t *msg, size_t len )
540{
541 if( mbedtls_a64_crypto_sha256_has_support() )
542 return( mbedtls_internal_sha256_process_many_a64_crypto( ctx, msg, len ) );
543 else
544 return( mbedtls_internal_sha256_process_many_c( ctx, msg, len ) );
545}
546
547int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
548 const unsigned char data[SHA256_BLOCK_SIZE] )
549{
550 if( mbedtls_a64_crypto_sha256_has_support() )
551 return( mbedtls_internal_sha256_process_a64_crypto( ctx, data ) );
552 else
553 return( mbedtls_internal_sha256_process_c( ctx, data ) );
554}
555
556#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
557
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
559/*
560 * SHA-256 process buffer
561 */
TRodziewicz26371e42021-06-08 16:45:41 +0200562int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100563 const unsigned char *input,
564 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000565{
Janos Follath24eed8d2019-11-22 13:21:35 +0000566 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000567 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000568 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
Brian White12895d12014-04-11 11:29:42 -0400570 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100571 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000572
573 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000574 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
Paul Bakker5c2364c2012-10-01 14:41:15 +0000576 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000577 ctx->total[0] &= 0xFFFFFFFF;
578
Paul Bakker5c2364c2012-10-01 14:41:15 +0000579 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000580 ctx->total[1]++;
581
582 if( left && ilen >= fill )
583 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200584 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100585
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100586 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100587 return( ret );
588
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 input += fill;
590 ilen -= fill;
591 left = 0;
592 }
593
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000594 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000596 size_t processed =
597 mbedtls_internal_sha256_process_many( ctx, input, ilen );
598 if( processed < SHA256_BLOCK_SIZE )
599 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100600
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000601 input += processed;
602 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000603 }
604
605 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200606 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100607
608 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609}
610
Paul Bakker5121ce52009-01-03 21:22:43 +0000611/*
612 * SHA-256 final digest
613 */
TRodziewicz26371e42021-06-08 16:45:41 +0200614int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200615 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000616{
Janos Follath24eed8d2019-11-22 13:21:35 +0000617 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200618 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000619 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200621 /*
622 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
623 */
624 used = ctx->total[0] & 0x3F;
625
626 ctx->buffer[used++] = 0x80;
627
628 if( used <= 56 )
629 {
630 /* Enough room for padding + length in current block */
631 memset( ctx->buffer + used, 0, 56 - used );
632 }
633 else
634 {
635 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000636 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200637
638 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
639 return( ret );
640
641 memset( ctx->buffer, 0, 56 );
642 }
643
644 /*
645 * Add message length
646 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000647 high = ( ctx->total[0] >> 29 )
648 | ( ctx->total[1] << 3 );
649 low = ( ctx->total[0] << 3 );
650
Joe Subbiani5ecac212021-06-24 13:00:03 +0100651 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
652 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000653
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200654 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100655 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100656
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200657 /*
658 * Output final state
659 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100660 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
661 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
662 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
663 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
664 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
665 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
666 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
David Horstmann687262c2022-10-06 17:54:57 +0100668 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200669#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100670 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200671#endif
David Horstmann687262c2022-10-06 17:54:57 +0100672 if( !truncated )
Joe Subbiani5ecac212021-06-24 13:00:03 +0100673 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100674
675 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000676}
677
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200678#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200679
Paul Bakker5121ce52009-01-03 21:22:43 +0000680/*
681 * output = SHA-256( input buffer )
682 */
TRodziewicz26371e42021-06-08 16:45:41 +0200683int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100684 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200685 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100686 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000687{
Janos Follath24eed8d2019-11-22 13:21:35 +0000688 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000690
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200691#if defined(MBEDTLS_SHA224_C)
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100692 if( is224 != 0 && is224 != 1 )
693 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200694#else
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100695 if( is224 != 0 )
696 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200697#endif
698
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100700
TRodziewicz26371e42021-06-08 16:45:41 +0200701 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100702 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100703
TRodziewicz26371e42021-06-08 16:45:41 +0200704 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100705 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100706
TRodziewicz26371e42021-06-08 16:45:41 +0200707 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100708 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100709
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100710exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100712
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100713 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000714}
715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000717/*
718 * FIPS-180-2 test vectors
719 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000720static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000721{
722 { "abc" },
723 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
724 { "" }
725};
726
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100727static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000728{
729 3, 56, 1000
730};
731
Paul Bakker9e36f042013-06-30 14:34:05 +0200732static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000733{
734 /*
735 * SHA-224 test vectors
736 */
737 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
738 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
739 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
740 0xE3, 0x6C, 0x9D, 0xA7 },
741 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
742 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
743 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
744 0x52, 0x52, 0x25, 0x25 },
745 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
746 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
747 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
748 0x4E, 0xE7, 0xAD, 0x67 },
749
750 /*
751 * SHA-256 test vectors
752 */
753 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
754 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
755 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
756 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
757 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
758 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
759 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
760 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
761 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
762 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
763 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
764 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
765};
766
767/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000768 * Checkup routine
769 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000771{
Paul Bakker5b4af392014-06-26 12:09:34 +0200772 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500773 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200774 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000776
Russ Butlerbb83b422016-10-12 17:36:50 -0500777 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
778 if( NULL == buf )
779 {
780 if( verbose != 0 )
781 mbedtls_printf( "Buffer allocation failed\n" );
782
783 return( 1 );
784 }
785
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200787
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 for( i = 0; i < 6; i++ )
789 {
790 j = i % 3;
791 k = i < 3;
792
793 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000795
TRodziewicz26371e42021-06-08 16:45:41 +0200796 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100797 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000798
799 if( j == 2 )
800 {
801 memset( buf, 'a', buflen = 1000 );
802
803 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100804 {
TRodziewicz26371e42021-06-08 16:45:41 +0200805 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100806 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100807 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100808 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100809
Paul Bakker5121ce52009-01-03 21:22:43 +0000810 }
811 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100812 {
TRodziewicz26371e42021-06-08 16:45:41 +0200813 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100814 sha256_test_buflen[j] );
815 if( ret != 0 )
816 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100817 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000818
TRodziewicz26371e42021-06-08 16:45:41 +0200819 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100820 goto fail;
821
Paul Bakker5121ce52009-01-03 21:22:43 +0000822
Paul Bakker9e36f042013-06-30 14:34:05 +0200823 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100824 {
825 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100826 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100827 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000828
829 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000831 }
832
833 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200834 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000835
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100836 goto exit;
837
838fail:
839 if( verbose != 0 )
840 mbedtls_printf( "failed\n" );
841
Paul Bakker5b4af392014-06-26 12:09:34 +0200842exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500844 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200845
846 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000847}
848
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000850
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851#endif /* MBEDTLS_SHA256_C */