blob: 2e65e6fd855dad4a9293d11be095994708dba56b [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020037#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010038
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000039#if defined(__aarch64__)
40# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
41 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
42# include <arm_neon.h>
43# endif
Tom Cosgroveb7f5b972022-03-15 11:26:55 +000044# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
45# if defined(__unix__)
46# if defined(__linux__)
47 /* Our preferred method of detection is getauxval() */
48# include <sys/auxv.h>
49# endif
50 /* Use SIGILL on Unix, and fall back to it on Linux */
51# include <signal.h>
52# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000053# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000054#elif defined(_M_ARM64)
55# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
56 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
57# include <arm64_neon.h>
58# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000059#else
60# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
61# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
62#endif
63
64#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
65/*
66 * Capability detection code comes early, so we can disable
67 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
68 */
69#if defined(HWCAP_SHA2)
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000070static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000071{
72 return( ( getauxval( AT_HWCAP ) & HWCAP_SHA2 ) ? 1 : 0 );
73}
74#elif defined(__APPLE__)
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000075static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000076{
77 return( 1 );
78}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000079#elif defined(_M_ARM64)
80#define WIN32_LEAN_AND_MEAN
81#include <Windows.h>
82#include <processthreadsapi.h>
83
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000084static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000085{
86 return( IsProcessorFeaturePresent( PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE ) ?
87 1 : 0 );
88}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000089#elif defined(__unix__) && defined(SIG_SETMASK)
90/* Detection with SIGILL, setjmp() and longjmp() */
91#include <signal.h>
92#include <setjmp.h>
93
94#ifndef asm
95#define asm __asm__
96#endif
97
98static jmp_buf return_from_sigill;
99
100/*
101 * A64 SHA256 support detection via SIGILL
102 */
103static void sigill_handler( int signal )
104{
105 (void) signal;
106 longjmp( return_from_sigill, 1 );
107}
108
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000109static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000110{
111 struct sigaction old_action, new_action;
112
113 sigset_t old_mask;
114 if( sigprocmask( 0, NULL, &old_mask ) )
115 return( 0 );
116
117 sigemptyset( &new_action.sa_mask );
118 new_action.sa_flags = 0;
119 new_action.sa_handler = sigill_handler;
120
121 sigaction( SIGILL, &new_action, &old_action );
122
123 static int ret = 0;
124
125 if( setjmp( return_from_sigill ) == 0 ) /* First return only */
126 {
127 /* If this traps, we will return a second time from setjmp() with 1 */
128 asm( "sha256h q0, q0, v0.4s" : : : "v0" );
129 ret = 1;
130 }
131
132 sigaction( SIGILL, &old_action, NULL );
133 sigprocmask( SIG_SETMASK, &old_mask, NULL );
134
135 return( ret );
136}
137#else
138#warning "No mechanism to detect A64_CRYPTO found, using C code only"
139#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
140#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
141
142#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
143
Hanno Becker2f6de422018-12-20 10:22:32 +0000144#define SHA256_VALIDATE_RET(cond) \
145 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
146#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
147
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200148#if !defined(MBEDTLS_SHA256_ALT)
149
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000150#define SHA256_BLOCK_SIZE 64
151
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200153{
Hanno Becker8d215e72018-12-18 17:53:21 +0000154 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000155
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200157}
158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200160{
161 if( ctx == NULL )
162 return;
163
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500164 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200165}
166
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200167void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
168 const mbedtls_sha256_context *src )
169{
Hanno Becker8d215e72018-12-18 17:53:21 +0000170 SHA256_VALIDATE( dst != NULL );
171 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000172
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200173 *dst = *src;
174}
175
Paul Bakker5121ce52009-01-03 21:22:43 +0000176/*
177 * SHA-256 context setup
178 */
TRodziewicz26371e42021-06-08 16:45:41 +0200179int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000180{
Hanno Becker8d215e72018-12-18 17:53:21 +0000181 SHA256_VALIDATE_RET( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000182
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200183#if defined(MBEDTLS_SHA224_C)
184 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
185#else
186 SHA256_VALIDATE_RET( is224 == 0 );
187#endif
188
Paul Bakker5121ce52009-01-03 21:22:43 +0000189 ctx->total[0] = 0;
190 ctx->total[1] = 0;
191
192 if( is224 == 0 )
193 {
194 /* SHA-256 */
195 ctx->state[0] = 0x6A09E667;
196 ctx->state[1] = 0xBB67AE85;
197 ctx->state[2] = 0x3C6EF372;
198 ctx->state[3] = 0xA54FF53A;
199 ctx->state[4] = 0x510E527F;
200 ctx->state[5] = 0x9B05688C;
201 ctx->state[6] = 0x1F83D9AB;
202 ctx->state[7] = 0x5BE0CD19;
203 }
204 else
205 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200206#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000207 /* SHA-224 */
208 ctx->state[0] = 0xC1059ED8;
209 ctx->state[1] = 0x367CD507;
210 ctx->state[2] = 0x3070DD17;
211 ctx->state[3] = 0xF70E5939;
212 ctx->state[4] = 0xFFC00B31;
213 ctx->state[5] = 0x68581511;
214 ctx->state[6] = 0x64F98FA7;
215 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200216#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000217 }
218
219 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100220
221 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000222}
223
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200225static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000226{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200227 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
228 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
229 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
230 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
231 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
232 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
233 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
234 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
235 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
236 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
237 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
238 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
239 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
240 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
241 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
242 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
243};
Paul Bakker5121ce52009-01-03 21:22:43 +0000244
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000245#endif
246
247#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
248 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
249
250#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
251# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
252# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
253#endif
254
255static size_t mbedtls_internal_sha256_process_many_a64_crypto(
256 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len )
257{
258 uint32x4_t abcd = vld1q_u32( &ctx->state[0] );
259 uint32x4_t efgh = vld1q_u32( &ctx->state[4] );
260
261 size_t processed = 0;
262
263 for( ;
264 len >= SHA256_BLOCK_SIZE;
265 processed += SHA256_BLOCK_SIZE,
266 msg += SHA256_BLOCK_SIZE,
267 len -= SHA256_BLOCK_SIZE )
268 {
269 uint32x4_t tmp, abcd_prev;
270
271 uint32x4_t abcd_orig = abcd;
272 uint32x4_t efgh_orig = efgh;
273
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000274 uint32x4_t sched0 = (uint32x4_t) vld1q_u8( msg + 16 * 0 );
275 uint32x4_t sched1 = (uint32x4_t) vld1q_u8( msg + 16 * 1 );
276 uint32x4_t sched2 = (uint32x4_t) vld1q_u8( msg + 16 * 2 );
277 uint32x4_t sched3 = (uint32x4_t) vld1q_u8( msg + 16 * 3 );
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000278
279#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
280 /* Untested on BE */
281 sched0 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched0 ) ) );
282 sched1 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched1 ) ) );
283 sched2 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched2 ) ) );
284 sched3 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched3 ) ) );
285#endif
286
287 /* Rounds 0 to 3 */
288 tmp = vaddq_u32( sched0, vld1q_u32( &K[0] ) );
289 abcd_prev = abcd;
290 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
291 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
292
293 /* Rounds 4 to 7 */
294 tmp = vaddq_u32( sched1, vld1q_u32( &K[4] ) );
295 abcd_prev = abcd;
296 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
297 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
298
299 /* Rounds 8 to 11 */
300 tmp = vaddq_u32( sched2, vld1q_u32( &K[8] ) );
301 abcd_prev = abcd;
302 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
303 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
304
305 /* Rounds 12 to 15 */
306 tmp = vaddq_u32( sched3, vld1q_u32( &K[12] ) );
307 abcd_prev = abcd;
308 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
309 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
310
311 for( int t = 16; t < 64; t += 16 )
312 {
313 /* Rounds t to t + 3 */
314 sched0 = vsha256su1q_u32( vsha256su0q_u32( sched0, sched1 ), sched2, sched3 );
315 tmp = vaddq_u32( sched0, vld1q_u32( &K[t] ) );
316 abcd_prev = abcd;
317 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
318 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
319
320 /* Rounds t + 4 to t + 7 */
321 sched1 = vsha256su1q_u32( vsha256su0q_u32( sched1, sched2 ), sched3, sched0 );
322 tmp = vaddq_u32( sched1, vld1q_u32( &K[t + 4] ) );
323 abcd_prev = abcd;
324 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
325 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
326
327 /* Rounds t + 8 to t + 11 */
328 sched2 = vsha256su1q_u32( vsha256su0q_u32( sched2, sched3 ), sched0, sched1 );
329 tmp = vaddq_u32( sched2, vld1q_u32( &K[t + 8] ) );
330 abcd_prev = abcd;
331 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
332 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
333
334 /* Rounds t + 12 to t + 15 */
335 sched3 = vsha256su1q_u32( vsha256su0q_u32( sched3, sched0 ), sched1, sched2 );
336 tmp = vaddq_u32( sched3, vld1q_u32( &K[t + 12] ) );
337 abcd_prev = abcd;
338 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
339 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
340 }
341
342 abcd = vaddq_u32( abcd, abcd_orig );
343 efgh = vaddq_u32( efgh, efgh_orig );
344 }
345
346 vst1q_u32( &ctx->state[0], abcd );
347 vst1q_u32( &ctx->state[4], efgh );
348
349 return( processed );
350}
351
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100352#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
353/*
354 * This function is for internal use only if we are building both C and A64
355 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
356 */
357static
358#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000359int mbedtls_internal_sha256_process_a64_crypto( mbedtls_sha256_context *ctx,
360 const unsigned char data[SHA256_BLOCK_SIZE] )
361{
362 return( ( mbedtls_internal_sha256_process_many_a64_crypto( ctx, data,
363 SHA256_BLOCK_SIZE ) == SHA256_BLOCK_SIZE ) ? 0 : -1 );
364}
365
366#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
367
368
369#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
370#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
371#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
372#endif
373
374
375#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
376 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
377
Hanno Becker1eeca412018-10-15 12:01:35 +0100378#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
379#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000380
381#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
382#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
383
384#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
385#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
386
Hanno Becker1eeca412018-10-15 12:01:35 +0100387#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
388#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200390#define R(t) \
391 ( \
392 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
393 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100394 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200396#define P(a,b,c,d,e,f,g,h,x,K) \
397 do \
398 { \
399 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
400 local.temp2 = S2(a) + F0((a),(b),(c)); \
401 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100402 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100404#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
405/*
406 * This function is for internal use only if we are building both C and A64
407 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
408 */
409static
410#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000411int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
412 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200413{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200414 struct
415 {
416 uint32_t temp1, temp2, W[64];
417 uint32_t A[8];
418 } local;
419
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200420 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
Hanno Becker8d215e72018-12-18 17:53:21 +0000422 SHA256_VALIDATE_RET( ctx != NULL );
423 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000424
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200425 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200426 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200427
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200428#if defined(MBEDTLS_SHA256_SMALLER)
429 for( i = 0; i < 64; i++ )
430 {
431 if( i < 16 )
Joe Subbiani6a506312021-07-07 16:56:29 +0100432 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200433 else
434 R( i );
435
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200436 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
437 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200438
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200439 local.temp1 = local.A[7]; local.A[7] = local.A[6];
440 local.A[6] = local.A[5]; local.A[5] = local.A[4];
441 local.A[4] = local.A[3]; local.A[3] = local.A[2];
442 local.A[2] = local.A[1]; local.A[1] = local.A[0];
443 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200444 }
445#else /* MBEDTLS_SHA256_SMALLER */
446 for( i = 0; i < 16; i++ )
Joe Subbiani6a506312021-07-07 16:56:29 +0100447 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200448
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200449 for( i = 0; i < 16; i += 8 )
450 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200451 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
452 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
453 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
454 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
455 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
456 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
457 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
458 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
459 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
460 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
461 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
462 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
463 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
464 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
465 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
466 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 +0200467 }
468
469 for( i = 16; i < 64; i += 8 )
470 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200471 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
472 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
473 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
474 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
475 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
476 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
477 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
478 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
479 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
480 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
481 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
482 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
483 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
484 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
485 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
486 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200487 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200488#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200489
490 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200491 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100492
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200493 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200494 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100495
496 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000497}
Jaeden Amero041039f2018-02-19 15:28:08 +0000498
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000499#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
500
501
502#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
503
504static size_t mbedtls_internal_sha256_process_many_c(
505 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len )
506{
507 size_t processed = 0;
508
509 while( len >= SHA256_BLOCK_SIZE )
510 {
511 if( mbedtls_internal_sha256_process_c( ctx, data ) != 0 )
512 return( 0 );
513
514 data += SHA256_BLOCK_SIZE;
515 len -= SHA256_BLOCK_SIZE;
516
517 processed += SHA256_BLOCK_SIZE;
518 }
519
520 return( processed );
521}
522
523#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
524
525
526#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
527
528static int mbedtls_a64_crypto_sha256_has_support( void )
529{
530 static int done = 0;
531 static int supported = 0;
532
533 if( !done )
534 {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000535 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000536 done = 1;
537 }
538
539 return( supported );
540}
541
542static size_t mbedtls_internal_sha256_process_many( mbedtls_sha256_context *ctx,
543 const uint8_t *msg, size_t len )
544{
545 if( mbedtls_a64_crypto_sha256_has_support() )
546 return( mbedtls_internal_sha256_process_many_a64_crypto( ctx, msg, len ) );
547 else
548 return( mbedtls_internal_sha256_process_many_c( ctx, msg, len ) );
549}
550
551int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
552 const unsigned char data[SHA256_BLOCK_SIZE] )
553{
554 if( mbedtls_a64_crypto_sha256_has_support() )
555 return( mbedtls_internal_sha256_process_a64_crypto( ctx, data ) );
556 else
557 return( mbedtls_internal_sha256_process_c( ctx, data ) );
558}
559
560#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
561
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
563/*
564 * SHA-256 process buffer
565 */
TRodziewicz26371e42021-06-08 16:45:41 +0200566int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100567 const unsigned char *input,
568 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000569{
Janos Follath24eed8d2019-11-22 13:21:35 +0000570 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000571 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000572 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
Hanno Becker8d215e72018-12-18 17:53:21 +0000574 SHA256_VALIDATE_RET( ctx != NULL );
575 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000576
Brian White12895d12014-04-11 11:29:42 -0400577 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100578 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
580 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000581 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
Paul Bakker5c2364c2012-10-01 14:41:15 +0000583 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 ctx->total[0] &= 0xFFFFFFFF;
585
Paul Bakker5c2364c2012-10-01 14:41:15 +0000586 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 ctx->total[1]++;
588
589 if( left && ilen >= fill )
590 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200591 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100592
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100593 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100594 return( ret );
595
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 input += fill;
597 ilen -= fill;
598 left = 0;
599 }
600
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000601 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000603 size_t processed =
604 mbedtls_internal_sha256_process_many( ctx, input, ilen );
605 if( processed < SHA256_BLOCK_SIZE )
606 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100607
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000608 input += processed;
609 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000610 }
611
612 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200613 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100614
615 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000616}
617
Paul Bakker5121ce52009-01-03 21:22:43 +0000618/*
619 * SHA-256 final digest
620 */
TRodziewicz26371e42021-06-08 16:45:41 +0200621int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200622 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000623{
Janos Follath24eed8d2019-11-22 13:21:35 +0000624 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200625 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000626 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Hanno Becker8d215e72018-12-18 17:53:21 +0000628 SHA256_VALIDATE_RET( ctx != NULL );
629 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000630
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200631 /*
632 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
633 */
634 used = ctx->total[0] & 0x3F;
635
636 ctx->buffer[used++] = 0x80;
637
638 if( used <= 56 )
639 {
640 /* Enough room for padding + length in current block */
641 memset( ctx->buffer + used, 0, 56 - used );
642 }
643 else
644 {
645 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000646 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200647
648 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
649 return( ret );
650
651 memset( ctx->buffer, 0, 56 );
652 }
653
654 /*
655 * Add message length
656 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 high = ( ctx->total[0] >> 29 )
658 | ( ctx->total[1] << 3 );
659 low = ( ctx->total[0] << 3 );
660
Joe Subbiani5ecac212021-06-24 13:00:03 +0100661 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
662 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000663
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200664 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100665 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100666
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200667 /*
668 * Output final state
669 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100670 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
671 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
672 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
673 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
674 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
675 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
676 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200678#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000679 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200680#endif
Joe Subbiani5ecac212021-06-24 13:00:03 +0100681 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100682
683 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000684}
685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200686#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200687
Paul Bakker5121ce52009-01-03 21:22:43 +0000688/*
689 * output = SHA-256( input buffer )
690 */
TRodziewicz26371e42021-06-08 16:45:41 +0200691int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100692 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200693 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100694 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000695{
Janos Follath24eed8d2019-11-22 13:21:35 +0000696 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200699#if defined(MBEDTLS_SHA224_C)
Hanno Becker8d215e72018-12-18 17:53:21 +0000700 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200701#else
702 SHA256_VALIDATE_RET( is224 == 0 );
703#endif
704
Hanno Becker8d215e72018-12-18 17:53:21 +0000705 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
706 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000707
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200708 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100709
TRodziewicz26371e42021-06-08 16:45:41 +0200710 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100711 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100712
TRodziewicz26371e42021-06-08 16:45:41 +0200713 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100714 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100715
TRodziewicz26371e42021-06-08 16:45:41 +0200716 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100717 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100718
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100719exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100721
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100722 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000723}
724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000726/*
727 * FIPS-180-2 test vectors
728 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000729static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000730{
731 { "abc" },
732 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
733 { "" }
734};
735
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100736static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000737{
738 3, 56, 1000
739};
740
Paul Bakker9e36f042013-06-30 14:34:05 +0200741static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000742{
743 /*
744 * SHA-224 test vectors
745 */
746 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
747 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
748 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
749 0xE3, 0x6C, 0x9D, 0xA7 },
750 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
751 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
752 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
753 0x52, 0x52, 0x25, 0x25 },
754 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
755 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
756 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
757 0x4E, 0xE7, 0xAD, 0x67 },
758
759 /*
760 * SHA-256 test vectors
761 */
762 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
763 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
764 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
765 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
766 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
767 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
768 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
769 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
770 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
771 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
772 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
773 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
774};
775
776/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000777 * Checkup routine
778 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000780{
Paul Bakker5b4af392014-06-26 12:09:34 +0200781 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500782 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200783 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
Russ Butlerbb83b422016-10-12 17:36:50 -0500786 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
787 if( NULL == buf )
788 {
789 if( verbose != 0 )
790 mbedtls_printf( "Buffer allocation failed\n" );
791
792 return( 1 );
793 }
794
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200795 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200796
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 for( i = 0; i < 6; i++ )
798 {
799 j = i % 3;
800 k = i < 3;
801
802 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000804
TRodziewicz26371e42021-06-08 16:45:41 +0200805 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100806 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000807
808 if( j == 2 )
809 {
810 memset( buf, 'a', buflen = 1000 );
811
812 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100813 {
TRodziewicz26371e42021-06-08 16:45:41 +0200814 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100815 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100816 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100817 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100818
Paul Bakker5121ce52009-01-03 21:22:43 +0000819 }
820 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100821 {
TRodziewicz26371e42021-06-08 16:45:41 +0200822 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100823 sha256_test_buflen[j] );
824 if( ret != 0 )
825 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100826 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000827
TRodziewicz26371e42021-06-08 16:45:41 +0200828 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100829 goto fail;
830
Paul Bakker5121ce52009-01-03 21:22:43 +0000831
Paul Bakker9e36f042013-06-30 14:34:05 +0200832 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100833 {
834 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100835 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100836 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000837
838 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000840 }
841
842 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000844
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100845 goto exit;
846
847fail:
848 if( verbose != 0 )
849 mbedtls_printf( "failed\n" );
850
Paul Bakker5b4af392014-06-26 12:09:34 +0200851exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500853 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200854
855 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000856}
857
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000859
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860#endif /* MBEDTLS_SHA256_C */