blob: 1a9a855fab19d86fd9ea4c94ea8ef73113d2aa2b [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
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{
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200170#if defined(MBEDTLS_SHA224_C)
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100171 if( is224 != 0 && is224 != 1 )
172 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200173#else
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100174 if( is224 != 0 )
175 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200176#endif
177
Paul Bakker5121ce52009-01-03 21:22:43 +0000178 ctx->total[0] = 0;
179 ctx->total[1] = 0;
180
181 if( is224 == 0 )
182 {
183 /* SHA-256 */
184 ctx->state[0] = 0x6A09E667;
185 ctx->state[1] = 0xBB67AE85;
186 ctx->state[2] = 0x3C6EF372;
187 ctx->state[3] = 0xA54FF53A;
188 ctx->state[4] = 0x510E527F;
189 ctx->state[5] = 0x9B05688C;
190 ctx->state[6] = 0x1F83D9AB;
191 ctx->state[7] = 0x5BE0CD19;
192 }
193 else
194 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200195#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000196 /* SHA-224 */
197 ctx->state[0] = 0xC1059ED8;
198 ctx->state[1] = 0x367CD507;
199 ctx->state[2] = 0x3070DD17;
200 ctx->state[3] = 0xF70E5939;
201 ctx->state[4] = 0xFFC00B31;
202 ctx->state[5] = 0x68581511;
203 ctx->state[6] = 0x64F98FA7;
204 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200205#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000206 }
207
208 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100209
210 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000211}
212
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200214static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000215{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200216 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
217 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
218 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
219 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
220 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
221 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
222 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
223 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
224 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
225 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
226 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
227 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
228 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
229 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
230 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
231 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
232};
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000234#endif
235
236#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
237 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
238
239#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
240# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
241# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
242#endif
243
244static size_t mbedtls_internal_sha256_process_many_a64_crypto(
245 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len )
246{
247 uint32x4_t abcd = vld1q_u32( &ctx->state[0] );
248 uint32x4_t efgh = vld1q_u32( &ctx->state[4] );
249
250 size_t processed = 0;
251
252 for( ;
253 len >= SHA256_BLOCK_SIZE;
254 processed += SHA256_BLOCK_SIZE,
255 msg += SHA256_BLOCK_SIZE,
256 len -= SHA256_BLOCK_SIZE )
257 {
258 uint32x4_t tmp, abcd_prev;
259
260 uint32x4_t abcd_orig = abcd;
261 uint32x4_t efgh_orig = efgh;
262
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000263 uint32x4_t sched0 = (uint32x4_t) vld1q_u8( msg + 16 * 0 );
264 uint32x4_t sched1 = (uint32x4_t) vld1q_u8( msg + 16 * 1 );
265 uint32x4_t sched2 = (uint32x4_t) vld1q_u8( msg + 16 * 2 );
266 uint32x4_t sched3 = (uint32x4_t) vld1q_u8( msg + 16 * 3 );
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000267
268#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
269 /* Untested on BE */
270 sched0 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched0 ) ) );
271 sched1 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched1 ) ) );
272 sched2 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched2 ) ) );
273 sched3 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched3 ) ) );
274#endif
275
276 /* Rounds 0 to 3 */
277 tmp = vaddq_u32( sched0, vld1q_u32( &K[0] ) );
278 abcd_prev = abcd;
279 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
280 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
281
282 /* Rounds 4 to 7 */
283 tmp = vaddq_u32( sched1, vld1q_u32( &K[4] ) );
284 abcd_prev = abcd;
285 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
286 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
287
288 /* Rounds 8 to 11 */
289 tmp = vaddq_u32( sched2, vld1q_u32( &K[8] ) );
290 abcd_prev = abcd;
291 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
292 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
293
294 /* Rounds 12 to 15 */
295 tmp = vaddq_u32( sched3, vld1q_u32( &K[12] ) );
296 abcd_prev = abcd;
297 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
298 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
299
300 for( int t = 16; t < 64; t += 16 )
301 {
302 /* Rounds t to t + 3 */
303 sched0 = vsha256su1q_u32( vsha256su0q_u32( sched0, sched1 ), sched2, sched3 );
304 tmp = vaddq_u32( sched0, vld1q_u32( &K[t] ) );
305 abcd_prev = abcd;
306 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
307 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
308
309 /* Rounds t + 4 to t + 7 */
310 sched1 = vsha256su1q_u32( vsha256su0q_u32( sched1, sched2 ), sched3, sched0 );
311 tmp = vaddq_u32( sched1, vld1q_u32( &K[t + 4] ) );
312 abcd_prev = abcd;
313 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
314 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
315
316 /* Rounds t + 8 to t + 11 */
317 sched2 = vsha256su1q_u32( vsha256su0q_u32( sched2, sched3 ), sched0, sched1 );
318 tmp = vaddq_u32( sched2, vld1q_u32( &K[t + 8] ) );
319 abcd_prev = abcd;
320 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
321 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
322
323 /* Rounds t + 12 to t + 15 */
324 sched3 = vsha256su1q_u32( vsha256su0q_u32( sched3, sched0 ), sched1, sched2 );
325 tmp = vaddq_u32( sched3, vld1q_u32( &K[t + 12] ) );
326 abcd_prev = abcd;
327 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
328 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
329 }
330
331 abcd = vaddq_u32( abcd, abcd_orig );
332 efgh = vaddq_u32( efgh, efgh_orig );
333 }
334
335 vst1q_u32( &ctx->state[0], abcd );
336 vst1q_u32( &ctx->state[4], efgh );
337
338 return( processed );
339}
340
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100341#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
342/*
343 * This function is for internal use only if we are building both C and A64
344 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
345 */
346static
347#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000348int mbedtls_internal_sha256_process_a64_crypto( mbedtls_sha256_context *ctx,
349 const unsigned char data[SHA256_BLOCK_SIZE] )
350{
351 return( ( mbedtls_internal_sha256_process_many_a64_crypto( ctx, data,
352 SHA256_BLOCK_SIZE ) == SHA256_BLOCK_SIZE ) ? 0 : -1 );
353}
354
355#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
356
357
358#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
359#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
360#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
361#endif
362
363
364#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
365 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
366
Hanno Becker1eeca412018-10-15 12:01:35 +0100367#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
368#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000369
370#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
371#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
372
373#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
374#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
375
Hanno Becker1eeca412018-10-15 12:01:35 +0100376#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
377#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200379#define R(t) \
380 ( \
381 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
382 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100383 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200385#define P(a,b,c,d,e,f,g,h,x,K) \
386 do \
387 { \
388 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
389 local.temp2 = S2(a) + F0((a),(b),(c)); \
390 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100391 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000392
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100393#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
394/*
395 * This function is for internal use only if we are building both C and A64
396 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
397 */
398static
399#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000400int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
401 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200402{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200403 struct
404 {
405 uint32_t temp1, temp2, W[64];
406 uint32_t A[8];
407 } local;
408
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200409 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200411 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200412 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200413
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200414#if defined(MBEDTLS_SHA256_SMALLER)
415 for( i = 0; i < 64; i++ )
416 {
417 if( i < 16 )
Joe Subbiani6a506312021-07-07 16:56:29 +0100418 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200419 else
420 R( i );
421
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200422 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
423 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200424
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200425 local.temp1 = local.A[7]; local.A[7] = local.A[6];
426 local.A[6] = local.A[5]; local.A[5] = local.A[4];
427 local.A[4] = local.A[3]; local.A[3] = local.A[2];
428 local.A[2] = local.A[1]; local.A[1] = local.A[0];
429 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200430 }
431#else /* MBEDTLS_SHA256_SMALLER */
432 for( i = 0; i < 16; i++ )
Joe Subbiani6a506312021-07-07 16:56:29 +0100433 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200434
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200435 for( i = 0; i < 16; i += 8 )
436 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200437 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
438 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
439 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
440 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
441 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
442 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
443 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
444 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
445 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
446 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
447 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
448 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
449 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
450 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
451 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
452 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 +0200453 }
454
455 for( i = 16; i < 64; i += 8 )
456 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200457 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
458 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
459 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
460 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
461 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
462 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
463 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
464 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
465 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
466 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
467 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
468 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
469 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
470 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
471 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
472 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200473 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200474#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200475
476 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200477 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100478
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200479 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200480 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100481
482 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000483}
Jaeden Amero041039f2018-02-19 15:28:08 +0000484
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000485#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
486
487
488#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
489
490static size_t mbedtls_internal_sha256_process_many_c(
491 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len )
492{
493 size_t processed = 0;
494
495 while( len >= SHA256_BLOCK_SIZE )
496 {
497 if( mbedtls_internal_sha256_process_c( ctx, data ) != 0 )
498 return( 0 );
499
500 data += SHA256_BLOCK_SIZE;
501 len -= SHA256_BLOCK_SIZE;
502
503 processed += SHA256_BLOCK_SIZE;
504 }
505
506 return( processed );
507}
508
509#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
510
511
512#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
513
514static int mbedtls_a64_crypto_sha256_has_support( void )
515{
516 static int done = 0;
517 static int supported = 0;
518
519 if( !done )
520 {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000521 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000522 done = 1;
523 }
524
525 return( supported );
526}
527
528static size_t mbedtls_internal_sha256_process_many( mbedtls_sha256_context *ctx,
529 const uint8_t *msg, size_t len )
530{
531 if( mbedtls_a64_crypto_sha256_has_support() )
532 return( mbedtls_internal_sha256_process_many_a64_crypto( ctx, msg, len ) );
533 else
534 return( mbedtls_internal_sha256_process_many_c( ctx, msg, len ) );
535}
536
537int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
538 const unsigned char data[SHA256_BLOCK_SIZE] )
539{
540 if( mbedtls_a64_crypto_sha256_has_support() )
541 return( mbedtls_internal_sha256_process_a64_crypto( ctx, data ) );
542 else
543 return( mbedtls_internal_sha256_process_c( ctx, data ) );
544}
545
546#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
547
Paul Bakker5121ce52009-01-03 21:22:43 +0000548
549/*
550 * SHA-256 process buffer
551 */
TRodziewicz26371e42021-06-08 16:45:41 +0200552int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100553 const unsigned char *input,
554 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000555{
Janos Follath24eed8d2019-11-22 13:21:35 +0000556 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000557 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000558 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000559
Brian White12895d12014-04-11 11:29:42 -0400560 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100561 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
563 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000564 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
Paul Bakker5c2364c2012-10-01 14:41:15 +0000566 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000567 ctx->total[0] &= 0xFFFFFFFF;
568
Paul Bakker5c2364c2012-10-01 14:41:15 +0000569 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 ctx->total[1]++;
571
572 if( left && ilen >= fill )
573 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200574 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100575
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100576 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100577 return( ret );
578
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 input += fill;
580 ilen -= fill;
581 left = 0;
582 }
583
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000584 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000585 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000586 size_t processed =
587 mbedtls_internal_sha256_process_many( ctx, input, ilen );
588 if( processed < SHA256_BLOCK_SIZE )
589 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100590
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000591 input += processed;
592 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 }
594
595 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200596 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100597
598 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000599}
600
Paul Bakker5121ce52009-01-03 21:22:43 +0000601/*
602 * SHA-256 final digest
603 */
TRodziewicz26371e42021-06-08 16:45:41 +0200604int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200605 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000606{
Janos Follath24eed8d2019-11-22 13:21:35 +0000607 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200608 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000609 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200611 /*
612 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
613 */
614 used = ctx->total[0] & 0x3F;
615
616 ctx->buffer[used++] = 0x80;
617
618 if( used <= 56 )
619 {
620 /* Enough room for padding + length in current block */
621 memset( ctx->buffer + used, 0, 56 - used );
622 }
623 else
624 {
625 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000626 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200627
628 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
629 return( ret );
630
631 memset( ctx->buffer, 0, 56 );
632 }
633
634 /*
635 * Add message length
636 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 high = ( ctx->total[0] >> 29 )
638 | ( ctx->total[1] << 3 );
639 low = ( ctx->total[0] << 3 );
640
Joe Subbiani5ecac212021-06-24 13:00:03 +0100641 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
642 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200644 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100645 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100646
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200647 /*
648 * Output final state
649 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100650 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
651 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
652 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
653 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
654 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
655 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
656 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000657
David Horstmann687262c2022-10-06 17:54:57 +0100658 int truncated = 0;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200659#if defined(MBEDTLS_SHA224_C)
David Horstmann687262c2022-10-06 17:54:57 +0100660 truncated = ctx->is224;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200661#endif
David Horstmann687262c2022-10-06 17:54:57 +0100662 if( !truncated )
Joe Subbiani5ecac212021-06-24 13:00:03 +0100663 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100664
665 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000666}
667
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200669
Paul Bakker5121ce52009-01-03 21:22:43 +0000670/*
671 * output = SHA-256( input buffer )
672 */
TRodziewicz26371e42021-06-08 16:45:41 +0200673int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100674 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200675 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100676 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000677{
Janos Follath24eed8d2019-11-22 13:21:35 +0000678 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200681#if defined(MBEDTLS_SHA224_C)
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100682 if( is224 != 0 && is224 != 1 )
683 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200684#else
Tuvshinzaya Erdenekhuu696dfb62022-08-05 15:59:19 +0100685 if( is224 != 0 )
686 return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200687#endif
688
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100690
TRodziewicz26371e42021-06-08 16:45:41 +0200691 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100692 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100693
TRodziewicz26371e42021-06-08 16:45:41 +0200694 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100695 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100696
TRodziewicz26371e42021-06-08 16:45:41 +0200697 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100698 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100699
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100700exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100702
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100703 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000704}
705
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000707/*
708 * FIPS-180-2 test vectors
709 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000710static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000711{
712 { "abc" },
713 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
714 { "" }
715};
716
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100717static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000718{
719 3, 56, 1000
720};
721
Paul Bakker9e36f042013-06-30 14:34:05 +0200722static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000723{
724 /*
725 * SHA-224 test vectors
726 */
727 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
728 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
729 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
730 0xE3, 0x6C, 0x9D, 0xA7 },
731 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
732 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
733 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
734 0x52, 0x52, 0x25, 0x25 },
735 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
736 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
737 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
738 0x4E, 0xE7, 0xAD, 0x67 },
739
740 /*
741 * SHA-256 test vectors
742 */
743 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
744 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
745 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
746 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
747 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
748 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
749 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
750 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
751 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
752 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
753 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
754 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
755};
756
757/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000758 * Checkup routine
759 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200760int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000761{
Paul Bakker5b4af392014-06-26 12:09:34 +0200762 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500763 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200764 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200765 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000766
Russ Butlerbb83b422016-10-12 17:36:50 -0500767 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
768 if( NULL == buf )
769 {
770 if( verbose != 0 )
771 mbedtls_printf( "Buffer allocation failed\n" );
772
773 return( 1 );
774 }
775
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200777
Paul Bakker5121ce52009-01-03 21:22:43 +0000778 for( i = 0; i < 6; i++ )
779 {
780 j = i % 3;
781 k = i < 3;
782
783 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
TRodziewicz26371e42021-06-08 16:45:41 +0200786 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100787 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000788
789 if( j == 2 )
790 {
791 memset( buf, 'a', buflen = 1000 );
792
793 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100794 {
TRodziewicz26371e42021-06-08 16:45:41 +0200795 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100796 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100797 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100798 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100799
Paul Bakker5121ce52009-01-03 21:22:43 +0000800 }
801 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100802 {
TRodziewicz26371e42021-06-08 16:45:41 +0200803 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100804 sha256_test_buflen[j] );
805 if( ret != 0 )
806 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100807 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000808
TRodziewicz26371e42021-06-08 16:45:41 +0200809 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100810 goto fail;
811
Paul Bakker5121ce52009-01-03 21:22:43 +0000812
Paul Bakker9e36f042013-06-30 14:34:05 +0200813 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100814 {
815 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100816 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100817 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000818
819 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000821 }
822
823 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100826 goto exit;
827
828fail:
829 if( verbose != 0 )
830 mbedtls_printf( "failed\n" );
831
Paul Bakker5b4af392014-06-26 12:09:34 +0200832exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500834 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200835
836 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000837}
838
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000840
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841#endif /* MBEDTLS_SHA256_C */