blob: f548c672ea726af62b6223df0eebc45af4307a30 [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
Hanno Becker2f6de422018-12-20 10:22:32 +000047#define SHA256_VALIDATE_RET(cond) \
48 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
49#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
50
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020051#if !defined(MBEDTLS_SHA256_ALT)
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020054{
Hanno Becker8d215e72018-12-18 17:53:21 +000055 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020058}
59
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020061{
62 if( ctx == NULL )
63 return;
64
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050065 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020066}
67
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020068void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
69 const mbedtls_sha256_context *src )
70{
Hanno Becker8d215e72018-12-18 17:53:21 +000071 SHA256_VALIDATE( dst != NULL );
72 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000073
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020074 *dst = *src;
75}
76
Paul Bakker5121ce52009-01-03 21:22:43 +000077/*
78 * SHA-256 context setup
79 */
TRodziewicz26371e42021-06-08 16:45:41 +020080int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +000081{
Hanno Becker8d215e72018-12-18 17:53:21 +000082 SHA256_VALIDATE_RET( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000083
Mateusz Starzyke3c48b42021-04-19 16:46:28 +020084#if defined(MBEDTLS_SHA224_C)
85 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
86#else
87 SHA256_VALIDATE_RET( is224 == 0 );
88#endif
89
Paul Bakker5121ce52009-01-03 21:22:43 +000090 ctx->total[0] = 0;
91 ctx->total[1] = 0;
92
93 if( is224 == 0 )
94 {
95 /* SHA-256 */
96 ctx->state[0] = 0x6A09E667;
97 ctx->state[1] = 0xBB67AE85;
98 ctx->state[2] = 0x3C6EF372;
99 ctx->state[3] = 0xA54FF53A;
100 ctx->state[4] = 0x510E527F;
101 ctx->state[5] = 0x9B05688C;
102 ctx->state[6] = 0x1F83D9AB;
103 ctx->state[7] = 0x5BE0CD19;
104 }
105 else
106 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200107#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000108 /* SHA-224 */
109 ctx->state[0] = 0xC1059ED8;
110 ctx->state[1] = 0x367CD507;
111 ctx->state[2] = 0x3070DD17;
112 ctx->state[3] = 0xF70E5939;
113 ctx->state[4] = 0xFFC00B31;
114 ctx->state[5] = 0x68581511;
115 ctx->state[6] = 0x64F98FA7;
116 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200117#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000118 }
119
120 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100121
122 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000123}
124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200126static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000127{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200128 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
129 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
130 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
131 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
132 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
133 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
134 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
135 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
136 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
137 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
138 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
139 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
140 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
141 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
142 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
143 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
144};
Paul Bakker5121ce52009-01-03 21:22:43 +0000145
Hanno Becker1eeca412018-10-15 12:01:35 +0100146#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
147#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000148
149#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
150#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
151
152#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
153#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
154
Hanno Becker1eeca412018-10-15 12:01:35 +0100155#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
156#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000157
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200158#define R(t) \
159 ( \
160 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
161 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100162 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000163
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200164#define P(a,b,c,d,e,f,g,h,x,K) \
165 do \
166 { \
167 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
168 local.temp2 = S2(a) + F0((a),(b),(c)); \
169 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100170 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000171
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100172int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100173 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200174{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200175 struct
176 {
177 uint32_t temp1, temp2, W[64];
178 uint32_t A[8];
179 } local;
180
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200181 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000182
Hanno Becker8d215e72018-12-18 17:53:21 +0000183 SHA256_VALIDATE_RET( ctx != NULL );
184 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000185
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200186 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200187 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200188
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200189#if defined(MBEDTLS_SHA256_SMALLER)
190 for( i = 0; i < 64; i++ )
191 {
192 if( i < 16 )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200193 GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200194 else
195 R( i );
196
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200197 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
198 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200199
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200200 local.temp1 = local.A[7]; local.A[7] = local.A[6];
201 local.A[6] = local.A[5]; local.A[5] = local.A[4];
202 local.A[4] = local.A[3]; local.A[3] = local.A[2];
203 local.A[2] = local.A[1]; local.A[1] = local.A[0];
204 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200205 }
206#else /* MBEDTLS_SHA256_SMALLER */
207 for( i = 0; i < 16; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200208 GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200209
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200210 for( i = 0; i < 16; i += 8 )
211 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200212 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
213 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
214 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
215 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
216 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
217 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
218 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
219 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
220 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
221 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
222 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
223 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
224 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
225 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
226 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
227 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 +0200228 }
229
230 for( i = 16; i < 64; i += 8 )
231 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200232 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
233 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
234 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
235 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
236 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
237 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
238 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
239 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
240 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
241 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
242 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
243 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
244 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
245 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
246 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
247 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200248 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200249#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200250
251 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200252 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100253
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200254 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200255 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100256
257 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000258}
Jaeden Amero041039f2018-02-19 15:28:08 +0000259
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000261
262/*
263 * SHA-256 process buffer
264 */
TRodziewicz26371e42021-06-08 16:45:41 +0200265int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100266 const unsigned char *input,
267 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000268{
Janos Follath24eed8d2019-11-22 13:21:35 +0000269 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000270 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000271 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000272
Hanno Becker8d215e72018-12-18 17:53:21 +0000273 SHA256_VALIDATE_RET( ctx != NULL );
274 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000275
Brian White12895d12014-04-11 11:29:42 -0400276 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100277 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000278
279 left = ctx->total[0] & 0x3F;
280 fill = 64 - left;
281
Paul Bakker5c2364c2012-10-01 14:41:15 +0000282 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 ctx->total[0] &= 0xFFFFFFFF;
284
Paul Bakker5c2364c2012-10-01 14:41:15 +0000285 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000286 ctx->total[1]++;
287
288 if( left && ilen >= fill )
289 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200290 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100291
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100292 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100293 return( ret );
294
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 input += fill;
296 ilen -= fill;
297 left = 0;
298 }
299
300 while( ilen >= 64 )
301 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100302 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100303 return( ret );
304
Paul Bakker5121ce52009-01-03 21:22:43 +0000305 input += 64;
306 ilen -= 64;
307 }
308
309 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200310 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100311
312 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313}
314
Paul Bakker5121ce52009-01-03 21:22:43 +0000315/*
316 * SHA-256 final digest
317 */
TRodziewicz26371e42021-06-08 16:45:41 +0200318int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200319 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000320{
Janos Follath24eed8d2019-11-22 13:21:35 +0000321 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200322 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000323 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000324
Hanno Becker8d215e72018-12-18 17:53:21 +0000325 SHA256_VALIDATE_RET( ctx != NULL );
326 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000327
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200328 /*
329 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
330 */
331 used = ctx->total[0] & 0x3F;
332
333 ctx->buffer[used++] = 0x80;
334
335 if( used <= 56 )
336 {
337 /* Enough room for padding + length in current block */
338 memset( ctx->buffer + used, 0, 56 - used );
339 }
340 else
341 {
342 /* We'll need an extra block */
343 memset( ctx->buffer + used, 0, 64 - used );
344
345 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
346 return( ret );
347
348 memset( ctx->buffer, 0, 56 );
349 }
350
351 /*
352 * Add message length
353 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000354 high = ( ctx->total[0] >> 29 )
355 | ( ctx->total[1] << 3 );
356 low = ( ctx->total[0] << 3 );
357
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200358 PUT_UINT32_BE( high, ctx->buffer, 56 );
359 PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200361 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100362 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100363
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200364 /*
365 * Output final state
366 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000367 PUT_UINT32_BE( ctx->state[0], output, 0 );
368 PUT_UINT32_BE( ctx->state[1], output, 4 );
369 PUT_UINT32_BE( ctx->state[2], output, 8 );
370 PUT_UINT32_BE( ctx->state[3], output, 12 );
371 PUT_UINT32_BE( ctx->state[4], output, 16 );
372 PUT_UINT32_BE( ctx->state[5], output, 20 );
373 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200375#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200377#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000378 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100379
380 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000381}
382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200384
Paul Bakker5121ce52009-01-03 21:22:43 +0000385/*
386 * output = SHA-256( input buffer )
387 */
TRodziewicz26371e42021-06-08 16:45:41 +0200388int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100389 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200390 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100391 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000392{
Janos Follath24eed8d2019-11-22 13:21:35 +0000393 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200396#if defined(MBEDTLS_SHA224_C)
Hanno Becker8d215e72018-12-18 17:53:21 +0000397 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200398#else
399 SHA256_VALIDATE_RET( is224 == 0 );
400#endif
401
Hanno Becker8d215e72018-12-18 17:53:21 +0000402 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
403 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100406
TRodziewicz26371e42021-06-08 16:45:41 +0200407 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100408 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100409
TRodziewicz26371e42021-06-08 16:45:41 +0200410 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100411 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100412
TRodziewicz26371e42021-06-08 16:45:41 +0200413 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100414 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100415
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100416exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100418
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100419 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000420}
421
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000423/*
424 * FIPS-180-2 test vectors
425 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000426static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000427{
428 { "abc" },
429 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
430 { "" }
431};
432
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100433static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000434{
435 3, 56, 1000
436};
437
Paul Bakker9e36f042013-06-30 14:34:05 +0200438static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000439{
440 /*
441 * SHA-224 test vectors
442 */
443 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
444 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
445 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
446 0xE3, 0x6C, 0x9D, 0xA7 },
447 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
448 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
449 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
450 0x52, 0x52, 0x25, 0x25 },
451 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
452 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
453 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
454 0x4E, 0xE7, 0xAD, 0x67 },
455
456 /*
457 * SHA-256 test vectors
458 */
459 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
460 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
461 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
462 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
463 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
464 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
465 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
466 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
467 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
468 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
469 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
470 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
471};
472
473/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000474 * Checkup routine
475 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000477{
Paul Bakker5b4af392014-06-26 12:09:34 +0200478 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500479 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200480 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Russ Butlerbb83b422016-10-12 17:36:50 -0500483 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
484 if( NULL == buf )
485 {
486 if( verbose != 0 )
487 mbedtls_printf( "Buffer allocation failed\n" );
488
489 return( 1 );
490 }
491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200493
Paul Bakker5121ce52009-01-03 21:22:43 +0000494 for( i = 0; i < 6; i++ )
495 {
496 j = i % 3;
497 k = i < 3;
498
499 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
TRodziewicz26371e42021-06-08 16:45:41 +0200502 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100503 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
505 if( j == 2 )
506 {
507 memset( buf, 'a', buflen = 1000 );
508
509 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100510 {
TRodziewicz26371e42021-06-08 16:45:41 +0200511 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100512 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100513 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100514 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100515
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 }
517 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100518 {
TRodziewicz26371e42021-06-08 16:45:41 +0200519 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100520 sha256_test_buflen[j] );
521 if( ret != 0 )
522 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100523 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
TRodziewicz26371e42021-06-08 16:45:41 +0200525 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100526 goto fail;
527
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
Paul Bakker9e36f042013-06-30 14:34:05 +0200529 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100530 {
531 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100532 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100533 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000534
535 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000537 }
538
539 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000541
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100542 goto exit;
543
544fail:
545 if( verbose != 0 )
546 mbedtls_printf( "failed\n" );
547
Paul Bakker5b4af392014-06-26 12:09:34 +0200548exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500550 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200551
552 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000553}
554
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000556
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557#endif /* MBEDTLS_SHA256_C */