blob: bdc396a1883f3946bc487dcbc5469b2d0d684bcd [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{
Hanno Becker8d215e72018-12-18 17:53:21 +0000162 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200165}
166
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200168{
169 if( ctx == NULL )
170 return;
171
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500172 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200173}
174
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200175void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
176 const mbedtls_sha256_context *src )
177{
Hanno Becker8d215e72018-12-18 17:53:21 +0000178 SHA256_VALIDATE( dst != NULL );
179 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000180
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200181 *dst = *src;
182}
183
Paul Bakker5121ce52009-01-03 21:22:43 +0000184/*
185 * SHA-256 context setup
186 */
TRodziewicz26371e42021-06-08 16:45:41 +0200187int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000188{
Hanno Becker8d215e72018-12-18 17:53:21 +0000189 SHA256_VALIDATE_RET( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000190
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200191#if defined(MBEDTLS_SHA224_C)
192 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
193#else
194 SHA256_VALIDATE_RET( is224 == 0 );
195#endif
196
Paul Bakker5121ce52009-01-03 21:22:43 +0000197 ctx->total[0] = 0;
198 ctx->total[1] = 0;
199
200 if( is224 == 0 )
201 {
202 /* SHA-256 */
203 ctx->state[0] = 0x6A09E667;
204 ctx->state[1] = 0xBB67AE85;
205 ctx->state[2] = 0x3C6EF372;
206 ctx->state[3] = 0xA54FF53A;
207 ctx->state[4] = 0x510E527F;
208 ctx->state[5] = 0x9B05688C;
209 ctx->state[6] = 0x1F83D9AB;
210 ctx->state[7] = 0x5BE0CD19;
211 }
212 else
213 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200214#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 /* SHA-224 */
216 ctx->state[0] = 0xC1059ED8;
217 ctx->state[1] = 0x367CD507;
218 ctx->state[2] = 0x3070DD17;
219 ctx->state[3] = 0xF70E5939;
220 ctx->state[4] = 0xFFC00B31;
221 ctx->state[5] = 0x68581511;
222 ctx->state[6] = 0x64F98FA7;
223 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200224#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000225 }
226
227 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100228
229 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000230}
231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200233static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000234{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200235 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
236 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
237 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
238 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
239 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
240 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
241 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
242 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
243 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
244 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
245 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
246 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
247 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
248 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
249 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
250 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
251};
Paul Bakker5121ce52009-01-03 21:22:43 +0000252
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000253#endif
254
255#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
256 defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
257
258#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
259# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
260# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
261#endif
262
263static size_t mbedtls_internal_sha256_process_many_a64_crypto(
264 mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len )
265{
266 uint32x4_t abcd = vld1q_u32( &ctx->state[0] );
267 uint32x4_t efgh = vld1q_u32( &ctx->state[4] );
268
269 size_t processed = 0;
270
271 for( ;
272 len >= SHA256_BLOCK_SIZE;
273 processed += SHA256_BLOCK_SIZE,
274 msg += SHA256_BLOCK_SIZE,
275 len -= SHA256_BLOCK_SIZE )
276 {
277 uint32x4_t tmp, abcd_prev;
278
279 uint32x4_t abcd_orig = abcd;
280 uint32x4_t efgh_orig = efgh;
281
Tom Cosgroveb7f5b972022-03-15 11:26:55 +0000282 uint32x4_t sched0 = (uint32x4_t) vld1q_u8( msg + 16 * 0 );
283 uint32x4_t sched1 = (uint32x4_t) vld1q_u8( msg + 16 * 1 );
284 uint32x4_t sched2 = (uint32x4_t) vld1q_u8( msg + 16 * 2 );
285 uint32x4_t sched3 = (uint32x4_t) vld1q_u8( msg + 16 * 3 );
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000286
287#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
288 /* Untested on BE */
289 sched0 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched0 ) ) );
290 sched1 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched1 ) ) );
291 sched2 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched2 ) ) );
292 sched3 = vreinterpretq_u32_u8( vrev32q_u8( vreinterpretq_u8_u32( sched3 ) ) );
293#endif
294
295 /* Rounds 0 to 3 */
296 tmp = vaddq_u32( sched0, vld1q_u32( &K[0] ) );
297 abcd_prev = abcd;
298 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
299 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
300
301 /* Rounds 4 to 7 */
302 tmp = vaddq_u32( sched1, vld1q_u32( &K[4] ) );
303 abcd_prev = abcd;
304 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
305 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
306
307 /* Rounds 8 to 11 */
308 tmp = vaddq_u32( sched2, vld1q_u32( &K[8] ) );
309 abcd_prev = abcd;
310 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
311 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
312
313 /* Rounds 12 to 15 */
314 tmp = vaddq_u32( sched3, vld1q_u32( &K[12] ) );
315 abcd_prev = abcd;
316 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
317 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
318
319 for( int t = 16; t < 64; t += 16 )
320 {
321 /* Rounds t to t + 3 */
322 sched0 = vsha256su1q_u32( vsha256su0q_u32( sched0, sched1 ), sched2, sched3 );
323 tmp = vaddq_u32( sched0, vld1q_u32( &K[t] ) );
324 abcd_prev = abcd;
325 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
326 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
327
328 /* Rounds t + 4 to t + 7 */
329 sched1 = vsha256su1q_u32( vsha256su0q_u32( sched1, sched2 ), sched3, sched0 );
330 tmp = vaddq_u32( sched1, vld1q_u32( &K[t + 4] ) );
331 abcd_prev = abcd;
332 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
333 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
334
335 /* Rounds t + 8 to t + 11 */
336 sched2 = vsha256su1q_u32( vsha256su0q_u32( sched2, sched3 ), sched0, sched1 );
337 tmp = vaddq_u32( sched2, vld1q_u32( &K[t + 8] ) );
338 abcd_prev = abcd;
339 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
340 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
341
342 /* Rounds t + 12 to t + 15 */
343 sched3 = vsha256su1q_u32( vsha256su0q_u32( sched3, sched0 ), sched1, sched2 );
344 tmp = vaddq_u32( sched3, vld1q_u32( &K[t + 12] ) );
345 abcd_prev = abcd;
346 abcd = vsha256hq_u32( abcd_prev, efgh, tmp );
347 efgh = vsha256h2q_u32( efgh, abcd_prev, tmp );
348 }
349
350 abcd = vaddq_u32( abcd, abcd_orig );
351 efgh = vaddq_u32( efgh, efgh_orig );
352 }
353
354 vst1q_u32( &ctx->state[0], abcd );
355 vst1q_u32( &ctx->state[4], efgh );
356
357 return( processed );
358}
359
360int 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 Cosgrovef3ebd902022-02-20 22:25:31 +0000405int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
406 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200407{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200408 struct
409 {
410 uint32_t temp1, temp2, W[64];
411 uint32_t A[8];
412 } local;
413
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200414 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Hanno Becker8d215e72018-12-18 17:53:21 +0000416 SHA256_VALIDATE_RET( ctx != NULL );
417 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000418
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200419 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200420 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200421
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200422#if defined(MBEDTLS_SHA256_SMALLER)
423 for( i = 0; i < 64; i++ )
424 {
425 if( i < 16 )
Joe Subbiani6a506312021-07-07 16:56:29 +0100426 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200427 else
428 R( i );
429
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200430 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
431 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200432
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200433 local.temp1 = local.A[7]; local.A[7] = local.A[6];
434 local.A[6] = local.A[5]; local.A[5] = local.A[4];
435 local.A[4] = local.A[3]; local.A[3] = local.A[2];
436 local.A[2] = local.A[1]; local.A[1] = local.A[0];
437 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200438 }
439#else /* MBEDTLS_SHA256_SMALLER */
440 for( i = 0; i < 16; i++ )
Joe Subbiani6a506312021-07-07 16:56:29 +0100441 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200442
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200443 for( i = 0; i < 16; i += 8 )
444 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200445 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
446 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
447 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
448 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
449 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
450 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
451 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
452 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
453 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
454 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
455 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
456 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
457 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
458 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
459 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
460 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 +0200461 }
462
463 for( i = 16; i < 64; i += 8 )
464 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200465 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
466 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
467 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
468 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
469 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
470 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
471 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
472 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
473 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
474 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
475 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
476 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
477 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
478 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
479 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
480 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200481 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200482#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200483
484 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200485 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100486
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200487 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200488 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100489
490 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491}
Jaeden Amero041039f2018-02-19 15:28:08 +0000492
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000493#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
494
495
496#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
497
498static size_t mbedtls_internal_sha256_process_many_c(
499 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len )
500{
501 size_t processed = 0;
502
503 while( len >= SHA256_BLOCK_SIZE )
504 {
505 if( mbedtls_internal_sha256_process_c( ctx, data ) != 0 )
506 return( 0 );
507
508 data += SHA256_BLOCK_SIZE;
509 len -= SHA256_BLOCK_SIZE;
510
511 processed += SHA256_BLOCK_SIZE;
512 }
513
514 return( processed );
515}
516
517#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
518
519
520#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
521
522static int mbedtls_a64_crypto_sha256_has_support( void )
523{
524 static int done = 0;
525 static int supported = 0;
526
527 if( !done )
528 {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000529 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000530 done = 1;
531 }
532
533 return( supported );
534}
535
536static size_t mbedtls_internal_sha256_process_many( mbedtls_sha256_context *ctx,
537 const uint8_t *msg, size_t len )
538{
539 if( mbedtls_a64_crypto_sha256_has_support() )
540 return( mbedtls_internal_sha256_process_many_a64_crypto( ctx, msg, len ) );
541 else
542 return( mbedtls_internal_sha256_process_many_c( ctx, msg, len ) );
543}
544
545int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
546 const unsigned char data[SHA256_BLOCK_SIZE] )
547{
548 if( mbedtls_a64_crypto_sha256_has_support() )
549 return( mbedtls_internal_sha256_process_a64_crypto( ctx, data ) );
550 else
551 return( mbedtls_internal_sha256_process_c( ctx, data ) );
552}
553
554#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
555
Paul Bakker5121ce52009-01-03 21:22:43 +0000556
557/*
558 * SHA-256 process buffer
559 */
TRodziewicz26371e42021-06-08 16:45:41 +0200560int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100561 const unsigned char *input,
562 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000563{
Janos Follath24eed8d2019-11-22 13:21:35 +0000564 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000565 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000566 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
Hanno Becker8d215e72018-12-18 17:53:21 +0000568 SHA256_VALIDATE_RET( ctx != NULL );
569 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000570
Brian White12895d12014-04-11 11:29:42 -0400571 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100572 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
574 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000575 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
Paul Bakker5c2364c2012-10-01 14:41:15 +0000577 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000578 ctx->total[0] &= 0xFFFFFFFF;
579
Paul Bakker5c2364c2012-10-01 14:41:15 +0000580 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000581 ctx->total[1]++;
582
583 if( left && ilen >= fill )
584 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200585 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100586
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100587 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100588 return( ret );
589
Paul Bakker5121ce52009-01-03 21:22:43 +0000590 input += fill;
591 ilen -= fill;
592 left = 0;
593 }
594
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000595 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000597 size_t processed =
598 mbedtls_internal_sha256_process_many( ctx, input, ilen );
599 if( processed < SHA256_BLOCK_SIZE )
600 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100601
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000602 input += processed;
603 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000604 }
605
606 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200607 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100608
609 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000610}
611
Paul Bakker5121ce52009-01-03 21:22:43 +0000612/*
613 * SHA-256 final digest
614 */
TRodziewicz26371e42021-06-08 16:45:41 +0200615int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200616 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000617{
Janos Follath24eed8d2019-11-22 13:21:35 +0000618 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200619 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000620 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Hanno Becker8d215e72018-12-18 17:53:21 +0000622 SHA256_VALIDATE_RET( ctx != NULL );
623 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000624
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200625 /*
626 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
627 */
628 used = ctx->total[0] & 0x3F;
629
630 ctx->buffer[used++] = 0x80;
631
632 if( used <= 56 )
633 {
634 /* Enough room for padding + length in current block */
635 memset( ctx->buffer + used, 0, 56 - used );
636 }
637 else
638 {
639 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000640 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200641
642 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
643 return( ret );
644
645 memset( ctx->buffer, 0, 56 );
646 }
647
648 /*
649 * Add message length
650 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 high = ( ctx->total[0] >> 29 )
652 | ( ctx->total[1] << 3 );
653 low = ( ctx->total[0] << 3 );
654
Joe Subbiani5ecac212021-06-24 13:00:03 +0100655 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
656 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000657
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200658 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100659 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100660
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200661 /*
662 * Output final state
663 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100664 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
665 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
666 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
667 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
668 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
669 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
670 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200672#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200674#endif
Joe Subbiani5ecac212021-06-24 13:00:03 +0100675 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100676
677 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000678}
679
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200681
Paul Bakker5121ce52009-01-03 21:22:43 +0000682/*
683 * output = SHA-256( input buffer )
684 */
TRodziewicz26371e42021-06-08 16:45:41 +0200685int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100686 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200687 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100688 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000689{
Janos Follath24eed8d2019-11-22 13:21:35 +0000690 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200693#if defined(MBEDTLS_SHA224_C)
Hanno Becker8d215e72018-12-18 17:53:21 +0000694 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200695#else
696 SHA256_VALIDATE_RET( is224 == 0 );
697#endif
698
Hanno Becker8d215e72018-12-18 17:53:21 +0000699 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
700 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000701
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100703
TRodziewicz26371e42021-06-08 16:45:41 +0200704 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100705 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100706
TRodziewicz26371e42021-06-08 16:45:41 +0200707 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100708 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100709
TRodziewicz26371e42021-06-08 16:45:41 +0200710 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100711 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100712
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100713exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100715
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100716 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000717}
718
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000720/*
721 * FIPS-180-2 test vectors
722 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000723static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000724{
725 { "abc" },
726 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
727 { "" }
728};
729
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100730static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000731{
732 3, 56, 1000
733};
734
Paul Bakker9e36f042013-06-30 14:34:05 +0200735static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000736{
737 /*
738 * SHA-224 test vectors
739 */
740 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
741 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
742 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
743 0xE3, 0x6C, 0x9D, 0xA7 },
744 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
745 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
746 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
747 0x52, 0x52, 0x25, 0x25 },
748 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
749 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
750 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
751 0x4E, 0xE7, 0xAD, 0x67 },
752
753 /*
754 * SHA-256 test vectors
755 */
756 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
757 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
758 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
759 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
760 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
761 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
762 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
763 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
764 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
765 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
766 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
767 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
768};
769
770/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000771 * Checkup routine
772 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000774{
Paul Bakker5b4af392014-06-26 12:09:34 +0200775 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500776 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200777 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200778 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
Russ Butlerbb83b422016-10-12 17:36:50 -0500780 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
781 if( NULL == buf )
782 {
783 if( verbose != 0 )
784 mbedtls_printf( "Buffer allocation failed\n" );
785
786 return( 1 );
787 }
788
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200790
Paul Bakker5121ce52009-01-03 21:22:43 +0000791 for( i = 0; i < 6; i++ )
792 {
793 j = i % 3;
794 k = i < 3;
795
796 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000798
TRodziewicz26371e42021-06-08 16:45:41 +0200799 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100800 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000801
802 if( j == 2 )
803 {
804 memset( buf, 'a', buflen = 1000 );
805
806 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100807 {
TRodziewicz26371e42021-06-08 16:45:41 +0200808 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100809 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100810 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100811 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100812
Paul Bakker5121ce52009-01-03 21:22:43 +0000813 }
814 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100815 {
TRodziewicz26371e42021-06-08 16:45:41 +0200816 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100817 sha256_test_buflen[j] );
818 if( ret != 0 )
819 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100820 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000821
TRodziewicz26371e42021-06-08 16:45:41 +0200822 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100823 goto fail;
824
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
Paul Bakker9e36f042013-06-30 14:34:05 +0200826 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100827 {
828 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100829 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100830 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000831
832 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000834 }
835
836 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100839 goto exit;
840
841fail:
842 if( verbose != 0 )
843 mbedtls_printf( "failed\n" );
844
Paul Bakker5b4af392014-06-26 12:09:34 +0200845exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500847 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200848
849 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000850}
851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000853
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854#endif /* MBEDTLS_SHA256_C */