blob: 24be8eac2bf8bc649c0f0528987a5fac14d3ad67 [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
Hanno Becker2f6de422018-12-20 10:22:32 +0000152#define SHA256_VALIDATE_RET(cond) \
153 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
154#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
155
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200156#if !defined(MBEDTLS_SHA256_ALT)
157
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000158#define SHA256_BLOCK_SIZE 64
159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200161{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200163}
164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200166{
167 if( ctx == NULL )
168 return;
169
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500170 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200171}
172
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200173void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
174 const mbedtls_sha256_context *src )
175{
176 *dst = *src;
177}
178
Paul Bakker5121ce52009-01-03 21:22:43 +0000179/*
180 * SHA-256 context setup
181 */
TRodziewicz26371e42021-06-08 16:45:41 +0200182int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000183{
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200184#if defined(MBEDTLS_SHA224_C)
185 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
186#else
187 SHA256_VALIDATE_RET( is224 == 0 );
188#endif
189
Paul Bakker5121ce52009-01-03 21:22:43 +0000190 ctx->total[0] = 0;
191 ctx->total[1] = 0;
192
193 if( is224 == 0 )
194 {
195 /* SHA-256 */
196 ctx->state[0] = 0x6A09E667;
197 ctx->state[1] = 0xBB67AE85;
198 ctx->state[2] = 0x3C6EF372;
199 ctx->state[3] = 0xA54FF53A;
200 ctx->state[4] = 0x510E527F;
201 ctx->state[5] = 0x9B05688C;
202 ctx->state[6] = 0x1F83D9AB;
203 ctx->state[7] = 0x5BE0CD19;
204 }
205 else
206 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200207#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000208 /* SHA-224 */
209 ctx->state[0] = 0xC1059ED8;
210 ctx->state[1] = 0x367CD507;
211 ctx->state[2] = 0x3070DD17;
212 ctx->state[3] = 0xF70E5939;
213 ctx->state[4] = 0xFFC00B31;
214 ctx->state[5] = 0x68581511;
215 ctx->state[6] = 0x64F98FA7;
216 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200217#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000218 }
219
220 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100221
222 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000223}
224
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200226static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000227{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200228 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
229 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
230 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
231 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
232 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
233 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
234 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
235 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
236 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
237 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
238 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
239 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
240 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
241 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
242 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
243 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
244};
Paul Bakker5121ce52009-01-03 21:22:43 +0000245
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000246#endif
247
248#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
249 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
250
251#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
252# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
253# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
254#endif
255
256static size_t mbedtls_internal_sha256_process_many_a64_crypto(
257 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len )
258{
259 uint32x4_t abcd = vld1q_u32( &ctx->state[0] );
260 uint32x4_t efgh = vld1q_u32( &ctx->state[4] );
261
262 size_t processed = 0;
263
264 for( ;
265 len >= SHA256_BLOCK_SIZE;
266 processed += SHA256_BLOCK_SIZE,
267 msg += SHA256_BLOCK_SIZE,
268 len -= SHA256_BLOCK_SIZE )
269 {
270 uint32x4_t tmp, abcd_prev;
271
272 uint32x4_t abcd_orig = abcd;
273 uint32x4_t efgh_orig = efgh;
274
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000275 uint32x4_t sched0 = (uint32x4_t) vld1q_u8( msg + 16 * 0 );
276 uint32x4_t sched1 = (uint32x4_t) vld1q_u8( msg + 16 * 1 );
277 uint32x4_t sched2 = (uint32x4_t) vld1q_u8( msg + 16 * 2 );
278 uint32x4_t sched3 = (uint32x4_t) vld1q_u8( msg + 16 * 3 );
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000279
280#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
281 /* Untested on BE */
282 sched0 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched0 ) ) );
283 sched1 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched1 ) ) );
284 sched2 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched2 ) ) );
285 sched3 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched3 ) ) );
286#endif
287
288 /* Rounds 0 to 3 */
289 tmp = vaddq_u32( sched0, vld1q_u32( &K[0] ) );
290 abcd_prev = abcd;
291 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
292 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
293
294 /* Rounds 4 to 7 */
295 tmp = vaddq_u32( sched1, vld1q_u32( &K[4] ) );
296 abcd_prev = abcd;
297 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
298 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
299
300 /* Rounds 8 to 11 */
301 tmp = vaddq_u32( sched2, vld1q_u32( &K[8] ) );
302 abcd_prev = abcd;
303 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
304 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
305
306 /* Rounds 12 to 15 */
307 tmp = vaddq_u32( sched3, vld1q_u32( &K[12] ) );
308 abcd_prev = abcd;
309 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
310 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
311
312 for( int t = 16; t < 64; t += 16 )
313 {
314 /* Rounds t to t + 3 */
315 sched0 = vsha256su1q_u32( vsha256su0q_u32( sched0, sched1 ), sched2, sched3 );
316 tmp = vaddq_u32( sched0, vld1q_u32( &K[t] ) );
317 abcd_prev = abcd;
318 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
319 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
320
321 /* Rounds t + 4 to t + 7 */
322 sched1 = vsha256su1q_u32( vsha256su0q_u32( sched1, sched2 ), sched3, sched0 );
323 tmp = vaddq_u32( sched1, vld1q_u32( &K[t + 4] ) );
324 abcd_prev = abcd;
325 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
326 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
327
328 /* Rounds t + 8 to t + 11 */
329 sched2 = vsha256su1q_u32( vsha256su0q_u32( sched2, sched3 ), sched0, sched1 );
330 tmp = vaddq_u32( sched2, vld1q_u32( &K[t + 8] ) );
331 abcd_prev = abcd;
332 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
333 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
334
335 /* Rounds t + 12 to t + 15 */
336 sched3 = vsha256su1q_u32( vsha256su0q_u32( sched3, sched0 ), sched1, sched2 );
337 tmp = vaddq_u32( sched3, vld1q_u32( &K[t + 12] ) );
338 abcd_prev = abcd;
339 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
340 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
341 }
342
343 abcd = vaddq_u32( abcd, abcd_orig );
344 efgh = vaddq_u32( efgh, efgh_orig );
345 }
346
347 vst1q_u32( &ctx->state[0], abcd );
348 vst1q_u32( &ctx->state[4], efgh );
349
350 return( processed );
351}
352
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100353#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
354/*
355 * This function is for internal use only if we are building both C and A64
356 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
357 */
358static
359#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000360int mbedtls_internal_sha256_process_a64_crypto( mbedtls_sha256_context *ctx,
361 const unsigned char data[SHA256_BLOCK_SIZE] )
362{
363 return( ( mbedtls_internal_sha256_process_many_a64_crypto( ctx, data,
364 SHA256_BLOCK_SIZE ) == SHA256_BLOCK_SIZE ) ? 0 : -1 );
365}
366
367#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
368
369
370#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
371#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
372#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
373#endif
374
375
376#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
377 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
378
Hanno Becker1eeca412018-10-15 12:01:35 +0100379#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
380#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
382#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
383#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
384
385#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
386#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
387
Hanno Becker1eeca412018-10-15 12:01:35 +0100388#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
389#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200391#define R(t) \
392 ( \
393 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
394 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100395 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200397#define P(a,b,c,d,e,f,g,h,x,K) \
398 do \
399 { \
400 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
401 local.temp2 = S2(a) + F0((a),(b),(c)); \
402 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100403 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100405#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
406/*
407 * This function is for internal use only if we are building both C and A64
408 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
409 */
410static
411#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000412int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
413 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200414{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200415 struct
416 {
417 uint32_t temp1, temp2, W[64];
418 uint32_t A[8];
419 } local;
420
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200421 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +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
Brian White12895d12014-04-11 11:29:42 -0400572 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100573 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
575 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000576 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
Paul Bakker5c2364c2012-10-01 14:41:15 +0000578 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 ctx->total[0] &= 0xFFFFFFFF;
580
Paul Bakker5c2364c2012-10-01 14:41:15 +0000581 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 ctx->total[1]++;
583
584 if( left && ilen >= fill )
585 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200586 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100587
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100588 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100589 return( ret );
590
Paul Bakker5121ce52009-01-03 21:22:43 +0000591 input += fill;
592 ilen -= fill;
593 left = 0;
594 }
595
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000596 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000597 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000598 size_t processed =
599 mbedtls_internal_sha256_process_many( ctx, input, ilen );
600 if( processed < SHA256_BLOCK_SIZE )
601 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100602
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000603 input += processed;
604 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000605 }
606
607 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200608 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100609
610 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611}
612
Paul Bakker5121ce52009-01-03 21:22:43 +0000613/*
614 * SHA-256 final digest
615 */
TRodziewicz26371e42021-06-08 16:45:41 +0200616int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200617 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000618{
Janos Follath24eed8d2019-11-22 13:21:35 +0000619 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200620 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000621 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200623 /*
624 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
625 */
626 used = ctx->total[0] & 0x3F;
627
628 ctx->buffer[used++] = 0x80;
629
630 if( used <= 56 )
631 {
632 /* Enough room for padding + length in current block */
633 memset( ctx->buffer + used, 0, 56 - used );
634 }
635 else
636 {
637 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000638 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200639
640 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
641 return( ret );
642
643 memset( ctx->buffer, 0, 56 );
644 }
645
646 /*
647 * Add message length
648 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000649 high = ( ctx->total[0] >> 29 )
650 | ( ctx->total[1] << 3 );
651 low = ( ctx->total[0] << 3 );
652
Joe Subbiani5ecac212021-06-24 13:00:03 +0100653 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
654 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000655
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200656 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100657 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100658
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200659 /*
660 * Output final state
661 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100662 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
663 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
664 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
665 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
666 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
667 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
668 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000669
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200670#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000671 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200672#endif
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)
Hanno Becker8d215e72018-12-18 17:53:21 +0000692 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200693#else
694 SHA256_VALIDATE_RET( is224 == 0 );
695#endif
696
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100698
TRodziewicz26371e42021-06-08 16:45:41 +0200699 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100700 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100701
TRodziewicz26371e42021-06-08 16:45:41 +0200702 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100703 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100704
TRodziewicz26371e42021-06-08 16:45:41 +0200705 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100706 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100707
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100708exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100710
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100711 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000712}
713
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000715/*
716 * FIPS-180-2 test vectors
717 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000718static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000719{
720 { "abc" },
721 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
722 { "" }
723};
724
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100725static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000726{
727 3, 56, 1000
728};
729
Paul Bakker9e36f042013-06-30 14:34:05 +0200730static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000731{
732 /*
733 * SHA-224 test vectors
734 */
735 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
736 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
737 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
738 0xE3, 0x6C, 0x9D, 0xA7 },
739 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
740 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
741 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
742 0x52, 0x52, 0x25, 0x25 },
743 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
744 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
745 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
746 0x4E, 0xE7, 0xAD, 0x67 },
747
748 /*
749 * SHA-256 test vectors
750 */
751 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
752 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
753 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
754 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
755 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
756 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
757 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
758 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
759 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
760 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
761 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
762 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
763};
764
765/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000766 * Checkup routine
767 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000769{
Paul Bakker5b4af392014-06-26 12:09:34 +0200770 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500771 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200772 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000774
Russ Butlerbb83b422016-10-12 17:36:50 -0500775 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
776 if( NULL == buf )
777 {
778 if( verbose != 0 )
779 mbedtls_printf( "Buffer allocation failed\n" );
780
781 return( 1 );
782 }
783
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200785
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 for( i = 0; i < 6; i++ )
787 {
788 j = i % 3;
789 k = i < 3;
790
791 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000793
TRodziewicz26371e42021-06-08 16:45:41 +0200794 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100795 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000796
797 if( j == 2 )
798 {
799 memset( buf, 'a', buflen = 1000 );
800
801 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100802 {
TRodziewicz26371e42021-06-08 16:45:41 +0200803 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100804 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100805 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100806 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100807
Paul Bakker5121ce52009-01-03 21:22:43 +0000808 }
809 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100810 {
TRodziewicz26371e42021-06-08 16:45:41 +0200811 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100812 sha256_test_buflen[j] );
813 if( ret != 0 )
814 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100815 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000816
TRodziewicz26371e42021-06-08 16:45:41 +0200817 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100818 goto fail;
819
Paul Bakker5121ce52009-01-03 21:22:43 +0000820
Paul Bakker9e36f042013-06-30 14:34:05 +0200821 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100822 {
823 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100824 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100825 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
827 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200828 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000829 }
830
831 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000833
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100834 goto exit;
835
836fail:
837 if( verbose != 0 )
838 mbedtls_printf( "failed\n" );
839
Paul Bakker5b4af392014-06-26 12:09:34 +0200840exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500842 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200843
844 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000845}
846
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000848
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849#endif /* MBEDTLS_SHA256_C */