blob: ac15ef8d1d160ddaae60fa9fcf0dd0da42340a49 [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
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100360#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
361/*
362 * This function is for internal use only if we are building both C and A64
363 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
364 */
365static
366#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000367int mbedtls_internal_sha256_process_a64_crypto( mbedtls_sha256_context *ctx,
368 const unsigned char data[SHA256_BLOCK_SIZE] )
369{
370 return( ( mbedtls_internal_sha256_process_many_a64_crypto( ctx, data,
371 SHA256_BLOCK_SIZE ) == SHA256_BLOCK_SIZE ) ? 0 : -1 );
372}
373
374#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
375
376
377#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
378#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
379#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
380#endif
381
382
383#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
384 !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
385
Hanno Becker1eeca412018-10-15 12:01:35 +0100386#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
387#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
389#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
390#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
391
392#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
393#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
394
Hanno Becker1eeca412018-10-15 12:01:35 +0100395#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
396#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200398#define R(t) \
399 ( \
400 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
401 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100402 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200404#define P(a,b,c,d,e,f,g,h,x,K) \
405 do \
406 { \
407 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
408 local.temp2 = S2(a) + F0((a),(b),(c)); \
409 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100410 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Tom Cosgrovec144ca62022-04-19 13:52:24 +0100412#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
413/*
414 * This function is for internal use only if we are building both C and A64
415 * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
416 */
417static
418#endif
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000419int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
420 const unsigned char data[SHA256_BLOCK_SIZE] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200421{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200422 struct
423 {
424 uint32_t temp1, temp2, W[64];
425 uint32_t A[8];
426 } local;
427
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200428 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Hanno Becker8d215e72018-12-18 17:53:21 +0000430 SHA256_VALIDATE_RET( ctx != NULL );
431 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000432
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200433 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200434 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200435
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200436#if defined(MBEDTLS_SHA256_SMALLER)
437 for( i = 0; i < 64; i++ )
438 {
439 if( i < 16 )
Joe Subbiani6a506312021-07-07 16:56:29 +0100440 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200441 else
442 R( i );
443
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200444 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
445 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200446
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200447 local.temp1 = local.A[7]; local.A[7] = local.A[6];
448 local.A[6] = local.A[5]; local.A[5] = local.A[4];
449 local.A[4] = local.A[3]; local.A[3] = local.A[2];
450 local.A[2] = local.A[1]; local.A[1] = local.A[0];
451 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200452 }
453#else /* MBEDTLS_SHA256_SMALLER */
454 for( i = 0; i < 16; i++ )
Joe Subbiani6a506312021-07-07 16:56:29 +0100455 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200456
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200457 for( i = 0; i < 16; i += 8 )
458 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200459 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
460 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
461 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
462 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
463 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
464 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
465 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
466 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
467 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
468 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
469 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
470 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
471 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
472 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
473 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
474 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 +0200475 }
476
477 for( i = 16; i < 64; i += 8 )
478 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200479 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
480 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
481 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
482 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
483 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
484 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
485 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
486 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
487 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
488 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
489 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
490 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
491 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
492 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
493 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
494 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200495 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200496#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200497
498 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200499 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100500
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200501 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200502 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100503
504 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000505}
Jaeden Amero041039f2018-02-19 15:28:08 +0000506
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000507#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
508
509
510#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
511
512static size_t mbedtls_internal_sha256_process_many_c(
513 mbedtls_sha256_context *ctx, const uint8_t *data, size_t len )
514{
515 size_t processed = 0;
516
517 while( len >= SHA256_BLOCK_SIZE )
518 {
519 if( mbedtls_internal_sha256_process_c( ctx, data ) != 0 )
520 return( 0 );
521
522 data += SHA256_BLOCK_SIZE;
523 len -= SHA256_BLOCK_SIZE;
524
525 processed += SHA256_BLOCK_SIZE;
526 }
527
528 return( processed );
529}
530
531#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
532
533
534#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
535
536static int mbedtls_a64_crypto_sha256_has_support( void )
537{
538 static int done = 0;
539 static int supported = 0;
540
541 if( !done )
542 {
Tom Cosgrove7e7aba82022-02-24 08:33:11 +0000543 supported = mbedtls_a64_crypto_sha256_determine_support();
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000544 done = 1;
545 }
546
547 return( supported );
548}
549
550static size_t mbedtls_internal_sha256_process_many( mbedtls_sha256_context *ctx,
551 const uint8_t *msg, size_t len )
552{
553 if( mbedtls_a64_crypto_sha256_has_support() )
554 return( mbedtls_internal_sha256_process_many_a64_crypto( ctx, msg, len ) );
555 else
556 return( mbedtls_internal_sha256_process_many_c( ctx, msg, len ) );
557}
558
559int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
560 const unsigned char data[SHA256_BLOCK_SIZE] )
561{
562 if( mbedtls_a64_crypto_sha256_has_support() )
563 return( mbedtls_internal_sha256_process_a64_crypto( ctx, data ) );
564 else
565 return( mbedtls_internal_sha256_process_c( ctx, data ) );
566}
567
568#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
569
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
571/*
572 * SHA-256 process buffer
573 */
TRodziewicz26371e42021-06-08 16:45:41 +0200574int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100575 const unsigned char *input,
576 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000577{
Janos Follath24eed8d2019-11-22 13:21:35 +0000578 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000579 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000580 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
Hanno Becker8d215e72018-12-18 17:53:21 +0000582 SHA256_VALIDATE_RET( ctx != NULL );
583 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000584
Brian White12895d12014-04-11 11:29:42 -0400585 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100586 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
588 left = ctx->total[0] & 0x3F;
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000589 fill = SHA256_BLOCK_SIZE - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000590
Paul Bakker5c2364c2012-10-01 14:41:15 +0000591 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000592 ctx->total[0] &= 0xFFFFFFFF;
593
Paul Bakker5c2364c2012-10-01 14:41:15 +0000594 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 ctx->total[1]++;
596
597 if( left && ilen >= fill )
598 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200599 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100600
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100601 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100602 return( ret );
603
Paul Bakker5121ce52009-01-03 21:22:43 +0000604 input += fill;
605 ilen -= fill;
606 left = 0;
607 }
608
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000609 while( ilen >= SHA256_BLOCK_SIZE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000610 {
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000611 size_t processed =
612 mbedtls_internal_sha256_process_many( ctx, input, ilen );
613 if( processed < SHA256_BLOCK_SIZE )
614 return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100615
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000616 input += processed;
617 ilen -= processed;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618 }
619
620 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200621 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100622
623 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000624}
625
Paul Bakker5121ce52009-01-03 21:22:43 +0000626/*
627 * SHA-256 final digest
628 */
TRodziewicz26371e42021-06-08 16:45:41 +0200629int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200630 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000631{
Janos Follath24eed8d2019-11-22 13:21:35 +0000632 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200633 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000634 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
Hanno Becker8d215e72018-12-18 17:53:21 +0000636 SHA256_VALIDATE_RET( ctx != NULL );
637 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000638
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200639 /*
640 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
641 */
642 used = ctx->total[0] & 0x3F;
643
644 ctx->buffer[used++] = 0x80;
645
646 if( used <= 56 )
647 {
648 /* Enough room for padding + length in current block */
649 memset( ctx->buffer + used, 0, 56 - used );
650 }
651 else
652 {
653 /* We'll need an extra block */
Tom Cosgrovef3ebd902022-02-20 22:25:31 +0000654 memset( ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200655
656 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
657 return( ret );
658
659 memset( ctx->buffer, 0, 56 );
660 }
661
662 /*
663 * Add message length
664 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 high = ( ctx->total[0] >> 29 )
666 | ( ctx->total[1] << 3 );
667 low = ( ctx->total[0] << 3 );
668
Joe Subbiani5ecac212021-06-24 13:00:03 +0100669 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
670 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200672 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100673 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100674
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200675 /*
676 * Output final state
677 */
Joe Subbiani5ecac212021-06-24 13:00:03 +0100678 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
679 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
680 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
681 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
682 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
683 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
684 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000685
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200686#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000687 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200688#endif
Joe Subbiani5ecac212021-06-24 13:00:03 +0100689 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100690
691 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000692}
693
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200695
Paul Bakker5121ce52009-01-03 21:22:43 +0000696/*
697 * output = SHA-256( input buffer )
698 */
TRodziewicz26371e42021-06-08 16:45:41 +0200699int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100700 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200701 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100702 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000703{
Janos Follath24eed8d2019-11-22 13:21:35 +0000704 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200707#if defined(MBEDTLS_SHA224_C)
Hanno Becker8d215e72018-12-18 17:53:21 +0000708 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200709#else
710 SHA256_VALIDATE_RET( is224 == 0 );
711#endif
712
Hanno Becker8d215e72018-12-18 17:53:21 +0000713 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
714 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100717
TRodziewicz26371e42021-06-08 16:45:41 +0200718 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100719 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100720
TRodziewicz26371e42021-06-08 16:45:41 +0200721 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100722 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100723
TRodziewicz26371e42021-06-08 16:45:41 +0200724 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100725 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100726
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100727exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100729
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100730 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000731}
732
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200733#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000734/*
735 * FIPS-180-2 test vectors
736 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000737static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000738{
739 { "abc" },
740 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
741 { "" }
742};
743
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100744static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000745{
746 3, 56, 1000
747};
748
Paul Bakker9e36f042013-06-30 14:34:05 +0200749static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000750{
751 /*
752 * SHA-224 test vectors
753 */
754 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
755 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
756 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
757 0xE3, 0x6C, 0x9D, 0xA7 },
758 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
759 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
760 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
761 0x52, 0x52, 0x25, 0x25 },
762 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
763 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
764 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
765 0x4E, 0xE7, 0xAD, 0x67 },
766
767 /*
768 * SHA-256 test vectors
769 */
770 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
771 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
772 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
773 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
774 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
775 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
776 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
777 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
778 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
779 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
780 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
781 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
782};
783
784/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000785 * Checkup routine
786 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000788{
Paul Bakker5b4af392014-06-26 12:09:34 +0200789 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500790 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200791 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000793
Russ Butlerbb83b422016-10-12 17:36:50 -0500794 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
795 if( NULL == buf )
796 {
797 if( verbose != 0 )
798 mbedtls_printf( "Buffer allocation failed\n" );
799
800 return( 1 );
801 }
802
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200804
Paul Bakker5121ce52009-01-03 21:22:43 +0000805 for( i = 0; i < 6; i++ )
806 {
807 j = i % 3;
808 k = i < 3;
809
810 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000812
TRodziewicz26371e42021-06-08 16:45:41 +0200813 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100814 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000815
816 if( j == 2 )
817 {
818 memset( buf, 'a', buflen = 1000 );
819
820 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100821 {
TRodziewicz26371e42021-06-08 16:45:41 +0200822 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100823 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100824 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100825 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100826
Paul Bakker5121ce52009-01-03 21:22:43 +0000827 }
828 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100829 {
TRodziewicz26371e42021-06-08 16:45:41 +0200830 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100831 sha256_test_buflen[j] );
832 if( ret != 0 )
833 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100834 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000835
TRodziewicz26371e42021-06-08 16:45:41 +0200836 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100837 goto fail;
838
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
Paul Bakker9e36f042013-06-30 14:34:05 +0200840 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100841 {
842 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100843 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100844 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000845
846 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000848 }
849
850 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000852
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100853 goto exit;
854
855fail:
856 if( verbose != 0 )
857 mbedtls_printf( "failed\n" );
858
Paul Bakker5b4af392014-06-26 12:09:34 +0200859exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500861 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200862
863 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000864}
865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000867
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868#endif /* MBEDTLS_SHA256_C */