blob: ff62802704ad553fe9ff16c81348c0dfc3cee2a7 [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
52# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) && defined(__linux__)
53# include <sys/auxv.h>
54# endif
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000055#elif defined(_M_ARM64)
56# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
57 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
58# include <arm64_neon.h>
59# endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000060#else
61# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
62# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
63#endif
64
65#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
66/*
67 * Capability detection code comes early, so we can disable
68 * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found
69 */
70#if defined(HWCAP_SHA2)
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000071static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000072{
73 return( ( getauxval( AT_HWCAP ) & HWCAP_SHA2 ) ? 1 : 0 );
74}
75#elif defined(__APPLE__)
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000076static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000077{
78 return( 1 );
79}
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000080#elif defined(_M_ARM64)
81#define WIN32_LEAN_AND_MEAN
82#include <Windows.h>
83#include <processthreadsapi.h>
84
Tom Cosgrove7e7aba82022-02-24 08:33:11 +000085static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgroveb9987fc2022-02-21 12:26:11 +000086{
87 return( IsProcessorFeaturePresent( PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE ) ?
88 1 : 0 );
89}
Tom Cosgrovef3ebd902022-02-20 22:25:31 +000090#elif defined(__unix__) && defined(SIG_SETMASK)
91/* Detection with SIGILL, setjmp() and longjmp() */
92#include <signal.h>
93#include <setjmp.h>
94
95#ifndef asm
96#define asm __asm__
97#endif
98
99static jmp_buf return_from_sigill;
100
101/*
102 * A64 SHA256 support detection via SIGILL
103 */
104static void sigill_handler( int signal )
105{
106 (void) signal;
107 longjmp( return_from_sigill, 1 );
108}
109
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000110static int mbedtls_a64_crypto_sha256_determine_support( void )
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000111{
112 struct sigaction old_action, new_action;
113
114 sigset_t old_mask;
115 if( sigprocmask( 0, NULL, &old_mask ) )
116 return( 0 );
117
118 sigemptyset( &new_action.sa_mask );
119 new_action.sa_flags = 0;
120 new_action.sa_handler = sigill_handler;
121
122 sigaction( SIGILL, &new_action, &old_action );
123
124 static int ret = 0;
125
126 if( setjmp( return_from_sigill ) == 0 ) /* First return only */
127 {
128 /* If this traps, we will return a second time from setjmp() with 1 */
129 asm( "sha256h q0, q0, v0.4s" : : : "v0" );
130 ret = 1;
131 }
132
133 sigaction( SIGILL, &old_action, NULL );
134 sigprocmask( SIG_SETMASK, &old_mask, NULL );
135
136 return( ret );
137}
138#else
139#warning "No mechanism to detect A64_CRYPTO found, using C code only"
140#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
141#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
142
143#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
144
Hanno Becker2f6de422018-12-20 10:22:32 +0000145#define SHA256_VALIDATE_RET(cond) \
146 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
147#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
148
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +0200149#if !defined(MBEDTLS_SHA256_ALT)
150
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000151#define SHA256_BLOCK_SIZE 64
152
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200153void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200154{
Hanno Becker8d215e72018-12-18 17:53:21 +0000155 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200158}
159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200161{
162 if( ctx == NULL )
163 return;
164
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500165 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200166}
167
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200168void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
169 const mbedtls_sha256_context *src )
170{
Hanno Becker8d215e72018-12-18 17:53:21 +0000171 SHA256_VALIDATE( dst != NULL );
172 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000173
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200174 *dst = *src;
175}
176
Paul Bakker5121ce52009-01-03 21:22:43 +0000177/*
178 * SHA-256 context setup
179 */
TRodziewicz26371e42021-06-08 16:45:41 +0200180int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000181{
Hanno Becker8d215e72018-12-18 17:53:21 +0000182 SHA256_VALIDATE_RET( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +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
275 uint32x4_t sched0 = vld1q_u32( (const uint32_t *)( msg + 16 * 0 ) );
276 uint32x4_t sched1 = vld1q_u32( (const uint32_t *)( msg + 16 * 1 ) );
277 uint32x4_t sched2 = vld1q_u32( (const uint32_t *)( msg + 16 * 2 ) );
278 uint32x4_t sched3 = vld1q_u32( (const uint32_t *)( msg + 16 * 3 ) );
279
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
353int mbedtls_internal_sha256_process_a64_crypto( mbedtls_sha256_context *ctx,
354 const unsigned char data[SHA256_BLOCK_SIZE] )
355{
356 return( ( mbedtls_internal_sha256_process_many_a64_crypto( ctx, data,
357 SHA256_BLOCK_SIZE ) == SHA256_BLOCK_SIZE ) ? 0 : -1 );
358}
359
360#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
361
362
363#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
364#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
365#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
366#endif
367
368
369#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
370 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
371
Hanno Becker1eeca412018-10-15 12:01:35 +0100372#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
373#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
375#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
376#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
377
378#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
379#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
380
Hanno Becker1eeca412018-10-15 12:01:35 +0100381#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
382#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200384#define R(t) \
385 ( \
386 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
387 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100388 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200390#define P(a,b,c,d,e,f,g,h,x,K) \
391 do \
392 { \
393 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
394 local.temp2 = S2(a) + F0((a),(b),(c)); \
395 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100396 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000398int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
399 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200400{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200401 struct
402 {
403 uint32_t temp1, temp2, W[64];
404 uint32_t A[8];
405 } local;
406
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200407 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Hanno Becker8d215e72018-12-18 17:53:21 +0000409 SHA256_VALIDATE_RET( ctx != NULL );
410 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000411
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200412 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200413 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200414
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200415#if defined(MBEDTLS_SHA256_SMALLER)
416 for( i = 0; i < 64; i++ )
417 {
418 if( i < 16 )
Joe Subbiani6a506312021-07-07 16:56:29 +0100419 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200420 else
421 R( i );
422
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200423 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
424 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200425
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200426 local.temp1 = local.A[7]; local.A[7] = local.A[6];
427 local.A[6] = local.A[5]; local.A[5] = local.A[4];
428 local.A[4] = local.A[3]; local.A[3] = local.A[2];
429 local.A[2] = local.A[1]; local.A[1] = local.A[0];
430 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200431 }
432#else /* MBEDTLS_SHA256_SMALLER */
433 for( i = 0; i < 16; i++ )
Joe Subbiani6a506312021-07-07 16:56:29 +0100434 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200435
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200436 for( i = 0; i < 16; i += 8 )
437 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200438 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
439 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
440 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
441 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
442 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
443 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
444 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
445 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
446 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
447 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
448 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
449 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
450 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
451 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
452 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
453 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 +0200454 }
455
456 for( i = 16; i < 64; i += 8 )
457 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200458 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
459 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
460 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
461 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
462 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
463 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
464 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
465 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
466 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
467 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
468 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
469 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
470 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
471 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
472 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
473 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200474 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200475#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200476
477 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200478 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100479
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200480 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200481 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100482
483 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000484}
Jaeden Amero041039f2018-02-19 15:28:08 +0000485
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000486#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
487
488
489#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
490
491static size_t mbedtls_internal_sha256_process_many_c(
492 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len )
493{
494 size_t processed = 0;
495
496 while( len >= SHA256_BLOCK_SIZE )
497 {
498 if( mbedtls_internal_sha256_process_c( ctx, data ) != 0 )
499 return( 0 );
500
501 data += SHA256_BLOCK_SIZE;
502 len -= SHA256_BLOCK_SIZE;
503
504 processed += SHA256_BLOCK_SIZE;
505 }
506
507 return( processed );
508}
509
510#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
511
512
513#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
514
515static int mbedtls_a64_crypto_sha256_has_support( void )
516{
517 static int done = 0;
518 static int supported = 0;
519
520 if( !done )
521 {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000522 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000523 done = 1;
524 }
525
526 return( supported );
527}
528
529static size_t mbedtls_internal_sha256_process_many( mbedtls_sha256_context *ctx,
530 const uint8_t *msg, size_t len )
531{
532 if( mbedtls_a64_crypto_sha256_has_support() )
533 return( mbedtls_internal_sha256_process_many_a64_crypto( ctx, msg, len ) );
534 else
535 return( mbedtls_internal_sha256_process_many_c( ctx, msg, len ) );
536}
537
538int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
539 const unsigned char data[SHA256_BLOCK_SIZE] )
540{
541 if( mbedtls_a64_crypto_sha256_has_support() )
542 return( mbedtls_internal_sha256_process_a64_crypto( ctx, data ) );
543 else
544 return( mbedtls_internal_sha256_process_c( ctx, data ) );
545}
546
547#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
548
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
550/*
551 * SHA-256 process buffer
552 */
TRodziewicz26371e42021-06-08 16:45:41 +0200553int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100554 const unsigned char *input,
555 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000556{
Janos Follath24eed8d2019-11-22 13:21:35 +0000557 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000558 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000559 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
Hanno Becker8d215e72018-12-18 17:53:21 +0000561 SHA256_VALIDATE_RET( ctx != NULL );
562 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000563
Brian White12895d12014-04-11 11:29:42 -0400564 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100565 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
567 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000568 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
Paul Bakker5c2364c2012-10-01 14:41:15 +0000570 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 ctx->total[0] &= 0xFFFFFFFF;
572
Paul Bakker5c2364c2012-10-01 14:41:15 +0000573 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000574 ctx->total[1]++;
575
576 if( left && ilen >= fill )
577 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200578 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100579
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100580 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100581 return( ret );
582
Paul Bakker5121ce52009-01-03 21:22:43 +0000583 input += fill;
584 ilen -= fill;
585 left = 0;
586 }
587
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000588 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000590 size_t processed =
591 mbedtls_internal_sha256_process_many( ctx, input, ilen );
592 if( processed < SHA256_BLOCK_SIZE )
593 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100594
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000595 input += processed;
596 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000597 }
598
599 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200600 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100601
602 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000603}
604
Paul Bakker5121ce52009-01-03 21:22:43 +0000605/*
606 * SHA-256 final digest
607 */
TRodziewicz26371e42021-06-08 16:45:41 +0200608int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200609 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000610{
Janos Follath24eed8d2019-11-22 13:21:35 +0000611 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200612 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000613 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
Hanno Becker8d215e72018-12-18 17:53:21 +0000615 SHA256_VALIDATE_RET( ctx != NULL );
616 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000617
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200618 /*
619 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
620 */
621 used = ctx->total[0] & 0x3F;
622
623 ctx->buffer[used++] = 0x80;
624
625 if( used <= 56 )
626 {
627 /* Enough room for padding + length in current block */
628 memset( ctx->buffer + used, 0, 56 - used );
629 }
630 else
631 {
632 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000633 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200634
635 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
636 return( ret );
637
638 memset( ctx->buffer, 0, 56 );
639 }
640
641 /*
642 * Add message length
643 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000644 high = ( ctx->total[0] >> 29 )
645 | ( ctx->total[1] << 3 );
646 low = ( ctx->total[0] << 3 );
647
Joe Subbiani5ecac212021-06-24 13:00:03 +0100648 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
649 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200651 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100652 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100653
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200654 /*
655 * Output final state
656 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100657 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
658 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
659 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
660 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
661 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
662 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
663 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200665#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200667#endif
Joe Subbiani5ecac212021-06-24 13:00:03 +0100668 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100669
670 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671}
672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200674
Paul Bakker5121ce52009-01-03 21:22:43 +0000675/*
676 * output = SHA-256( input buffer )
677 */
TRodziewicz26371e42021-06-08 16:45:41 +0200678int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100679 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200680 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100681 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000682{
Janos Follath24eed8d2019-11-22 13:21:35 +0000683 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000685
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200686#if defined(MBEDTLS_SHA224_C)
Hanno Becker8d215e72018-12-18 17:53:21 +0000687 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200688#else
689 SHA256_VALIDATE_RET( is224 == 0 );
690#endif
691
Hanno Becker8d215e72018-12-18 17:53:21 +0000692 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
693 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000694
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100696
TRodziewicz26371e42021-06-08 16:45:41 +0200697 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100698 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100699
TRodziewicz26371e42021-06-08 16:45:41 +0200700 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100701 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100702
TRodziewicz26371e42021-06-08 16:45:41 +0200703 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100704 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100705
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100706exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100708
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100709 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000710}
711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000713/*
714 * FIPS-180-2 test vectors
715 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000716static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000717{
718 { "abc" },
719 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
720 { "" }
721};
722
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100723static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000724{
725 3, 56, 1000
726};
727
Paul Bakker9e36f042013-06-30 14:34:05 +0200728static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000729{
730 /*
731 * SHA-224 test vectors
732 */
733 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
734 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
735 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
736 0xE3, 0x6C, 0x9D, 0xA7 },
737 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
738 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
739 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
740 0x52, 0x52, 0x25, 0x25 },
741 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
742 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
743 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
744 0x4E, 0xE7, 0xAD, 0x67 },
745
746 /*
747 * SHA-256 test vectors
748 */
749 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
750 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
751 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
752 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
753 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
754 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
755 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
756 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
757 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
758 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
759 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
760 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
761};
762
763/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000764 * Checkup routine
765 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200766int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000767{
Paul Bakker5b4af392014-06-26 12:09:34 +0200768 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500769 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200770 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000772
Russ Butlerbb83b422016-10-12 17:36:50 -0500773 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
774 if( NULL == buf )
775 {
776 if( verbose != 0 )
777 mbedtls_printf( "Buffer allocation failed\n" );
778
779 return( 1 );
780 }
781
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200783
Paul Bakker5121ce52009-01-03 21:22:43 +0000784 for( i = 0; i < 6; i++ )
785 {
786 j = i % 3;
787 k = i < 3;
788
789 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000791
TRodziewicz26371e42021-06-08 16:45:41 +0200792 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100793 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000794
795 if( j == 2 )
796 {
797 memset( buf, 'a', buflen = 1000 );
798
799 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100800 {
TRodziewicz26371e42021-06-08 16:45:41 +0200801 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100802 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100803 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100804 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100805
Paul Bakker5121ce52009-01-03 21:22:43 +0000806 }
807 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100808 {
TRodziewicz26371e42021-06-08 16:45:41 +0200809 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100810 sha256_test_buflen[j] );
811 if( ret != 0 )
812 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100813 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000814
TRodziewicz26371e42021-06-08 16:45:41 +0200815 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100816 goto fail;
817
Paul Bakker5121ce52009-01-03 21:22:43 +0000818
Paul Bakker9e36f042013-06-30 14:34:05 +0200819 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100820 {
821 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100822 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100823 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000824
825 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000827 }
828
829 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000831
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100832 goto exit;
833
834fail:
835 if( verbose != 0 )
836 mbedtls_printf( "failed\n" );
837
Paul Bakker5b4af392014-06-26 12:09:34 +0200838exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500840 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200841
842 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000843}
844
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000846
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847#endif /* MBEDTLS_SHA256_C */