blob: 256102fe432579b62b6e6cc7649d1238db47421d [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <string.h>
34
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020037#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010038
Hanno Becker2f6de422018-12-20 10:22:32 +000039#define SHA256_VALIDATE_RET(cond) \
40 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
41#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
42
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020043#if !defined(MBEDTLS_SHA256_ALT)
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020046{
Hanno Becker8d215e72018-12-18 17:53:21 +000047 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020050}
51
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020053{
54 if( ctx == NULL )
55 return;
56
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050057 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020058}
59
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020060void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
61 const mbedtls_sha256_context *src )
62{
Hanno Becker8d215e72018-12-18 17:53:21 +000063 SHA256_VALIDATE( dst != NULL );
64 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000065
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020066 *dst = *src;
67}
68
Paul Bakker5121ce52009-01-03 21:22:43 +000069/*
70 * SHA-256 context setup
71 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010072int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +000073{
Hanno Becker8d215e72018-12-18 17:53:21 +000074 SHA256_VALIDATE_RET( ctx != NULL );
75 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000076
Paul Bakker5121ce52009-01-03 21:22:43 +000077 ctx->total[0] = 0;
78 ctx->total[1] = 0;
79
80 if( is224 == 0 )
81 {
82 /* SHA-256 */
83 ctx->state[0] = 0x6A09E667;
84 ctx->state[1] = 0xBB67AE85;
85 ctx->state[2] = 0x3C6EF372;
86 ctx->state[3] = 0xA54FF53A;
87 ctx->state[4] = 0x510E527F;
88 ctx->state[5] = 0x9B05688C;
89 ctx->state[6] = 0x1F83D9AB;
90 ctx->state[7] = 0x5BE0CD19;
91 }
92 else
93 {
94 /* SHA-224 */
95 ctx->state[0] = 0xC1059ED8;
96 ctx->state[1] = 0x367CD507;
97 ctx->state[2] = 0x3070DD17;
98 ctx->state[3] = 0xF70E5939;
99 ctx->state[4] = 0xFFC00B31;
100 ctx->state[5] = 0x68581511;
101 ctx->state[6] = 0x64F98FA7;
102 ctx->state[7] = 0xBEFA4FA4;
103 }
104
105 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100106
107 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000108}
109
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200110#if !defined(MBEDTLS_DEPRECATED_REMOVED)
111void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
112 int is224 )
113{
114 mbedtls_sha256_starts_ret( ctx, is224 );
115}
116#endif
117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200119static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000120{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200121 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
122 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
123 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
124 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
125 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
126 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
127 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
128 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
129 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
130 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
131 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
132 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
133 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
134 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
135 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
136 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
137};
Paul Bakker5121ce52009-01-03 21:22:43 +0000138
Hanno Becker1eeca412018-10-15 12:01:35 +0100139#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
140#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000141
142#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
143#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
144
145#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
146#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
147
Hanno Becker1eeca412018-10-15 12:01:35 +0100148#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
149#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000150
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200151#define R(t) \
152 ( \
153 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
154 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100155 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000156
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200157#define P(a,b,c,d,e,f,g,h,x,K) \
158 do \
159 { \
160 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
161 local.temp2 = S2(a) + F0((a),(b),(c)); \
162 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100163 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100165int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100166 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200167{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200168 struct
169 {
170 uint32_t temp1, temp2, W[64];
171 uint32_t A[8];
172 } local;
173
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200174 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000175
Hanno Becker8d215e72018-12-18 17:53:21 +0000176 SHA256_VALIDATE_RET( ctx != NULL );
177 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000178
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200179 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200180 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200181
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200182#if defined(MBEDTLS_SHA256_SMALLER)
183 for( i = 0; i < 64; i++ )
184 {
185 if( i < 16 )
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100186 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200187 else
188 R( i );
189
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200190 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
191 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200192
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200193 local.temp1 = local.A[7]; local.A[7] = local.A[6];
194 local.A[6] = local.A[5]; local.A[5] = local.A[4];
195 local.A[4] = local.A[3]; local.A[3] = local.A[2];
196 local.A[2] = local.A[1]; local.A[1] = local.A[0];
197 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200198 }
199#else /* MBEDTLS_SHA256_SMALLER */
200 for( i = 0; i < 16; i++ )
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100201 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200202
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200203 for( i = 0; i < 16; i += 8 )
204 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200205 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
206 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
207 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
208 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
209 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
210 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
211 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
212 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
213 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
214 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
215 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
216 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
217 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
218 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
219 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
220 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 +0200221 }
222
223 for( i = 16; i < 64; i += 8 )
224 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200225 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
226 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
227 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
228 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
229 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
230 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
231 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
232 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
233 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
234 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
235 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
236 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
237 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
238 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
239 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
240 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200241 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200242#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200243
244 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200245 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100246
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200247 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200248 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100249
250 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000251}
Jaeden Amero041039f2018-02-19 15:28:08 +0000252
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200253#if !defined(MBEDTLS_DEPRECATED_REMOVED)
254void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
255 const unsigned char data[64] )
256{
257 mbedtls_internal_sha256_process( ctx, data );
258}
259#endif
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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100265int mbedtls_sha256_update_ret( 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
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200315#if !defined(MBEDTLS_DEPRECATED_REMOVED)
316void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
317 const unsigned char *input,
318 size_t ilen )
319{
320 mbedtls_sha256_update_ret( ctx, input, ilen );
321}
322#endif
323
Paul Bakker5121ce52009-01-03 21:22:43 +0000324/*
325 * SHA-256 final digest
326 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100327int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100328 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000329{
Janos Follath24eed8d2019-11-22 13:21:35 +0000330 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200331 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000332 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Hanno Becker8d215e72018-12-18 17:53:21 +0000334 SHA256_VALIDATE_RET( ctx != NULL );
335 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000336
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200337 /*
338 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
339 */
340 used = ctx->total[0] & 0x3F;
341
342 ctx->buffer[used++] = 0x80;
343
344 if( used <= 56 )
345 {
346 /* Enough room for padding + length in current block */
347 memset( ctx->buffer + used, 0, 56 - used );
348 }
349 else
350 {
351 /* We'll need an extra block */
352 memset( ctx->buffer + used, 0, 64 - used );
353
354 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
355 return( ret );
356
357 memset( ctx->buffer, 0, 56 );
358 }
359
360 /*
361 * Add message length
362 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000363 high = ( ctx->total[0] >> 29 )
364 | ( ctx->total[1] << 3 );
365 low = ( ctx->total[0] << 3 );
366
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100367 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
368 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000369
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200370 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100371 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100372
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200373 /*
374 * Output final state
375 */
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100376 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
377 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
378 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
379 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
380 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
381 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
382 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
384 if( ctx->is224 == 0 )
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100385 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100386
387 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000388}
389
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200390#if !defined(MBEDTLS_DEPRECATED_REMOVED)
391void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
392 unsigned char output[32] )
393{
394 mbedtls_sha256_finish_ret( ctx, output );
395}
396#endif
397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200399
Paul Bakker5121ce52009-01-03 21:22:43 +0000400/*
401 * output = SHA-256( input buffer )
402 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100403int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100404 size_t ilen,
405 unsigned char output[32],
406 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000407{
Janos Follath24eed8d2019-11-22 13:21:35 +0000408 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Hanno Becker8d215e72018-12-18 17:53:21 +0000411 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
412 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
413 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000414
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100416
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100417 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100418 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100419
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100420 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100421 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100422
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100423 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100424 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100425
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100426exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100428
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100429 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000430}
431
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200432#if !defined(MBEDTLS_DEPRECATED_REMOVED)
433void mbedtls_sha256( const unsigned char *input,
434 size_t ilen,
435 unsigned char output[32],
436 int is224 )
437{
438 mbedtls_sha256_ret( input, ilen, output, is224 );
439}
440#endif
441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000443/*
444 * FIPS-180-2 test vectors
445 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000446static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000447{
448 { "abc" },
449 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
450 { "" }
451};
452
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100453static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000454{
455 3, 56, 1000
456};
457
Paul Bakker9e36f042013-06-30 14:34:05 +0200458static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000459{
460 /*
461 * SHA-224 test vectors
462 */
463 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
464 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
465 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
466 0xE3, 0x6C, 0x9D, 0xA7 },
467 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
468 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
469 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
470 0x52, 0x52, 0x25, 0x25 },
471 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
472 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
473 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
474 0x4E, 0xE7, 0xAD, 0x67 },
475
476 /*
477 * SHA-256 test vectors
478 */
479 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
480 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
481 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
482 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
483 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
484 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
485 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
486 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
487 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
488 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
489 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
490 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
491};
492
493/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000494 * Checkup routine
495 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000497{
Paul Bakker5b4af392014-06-26 12:09:34 +0200498 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500499 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200500 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000502
Russ Butlerbb83b422016-10-12 17:36:50 -0500503 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
504 if( NULL == buf )
505 {
506 if( verbose != 0 )
507 mbedtls_printf( "Buffer allocation failed\n" );
508
509 return( 1 );
510 }
511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200513
Paul Bakker5121ce52009-01-03 21:22:43 +0000514 for( i = 0; i < 6; i++ )
515 {
516 j = i % 3;
517 k = i < 3;
518
519 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000521
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100522 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100523 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
525 if( j == 2 )
526 {
527 memset( buf, 'a', buflen = 1000 );
528
529 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100530 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100531 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100532 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100533 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100534 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100535
Paul Bakker5121ce52009-01-03 21:22:43 +0000536 }
537 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100538 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100539 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100540 sha256_test_buflen[j] );
541 if( ret != 0 )
542 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100543 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000544
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100545 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100546 goto fail;
547
Paul Bakker5121ce52009-01-03 21:22:43 +0000548
Paul Bakker9e36f042013-06-30 14:34:05 +0200549 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100550 {
551 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100552 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100553 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
555 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000557 }
558
559 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000561
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100562 goto exit;
563
564fail:
565 if( verbose != 0 )
566 mbedtls_printf( "failed\n" );
567
Paul Bakker5b4af392014-06-26 12:09:34 +0200568exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500570 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200571
572 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000573}
574
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577#endif /* MBEDTLS_SHA256_C */