blob: a63892fe1932ac0250b0b3d11ffbba86ac4bcebd [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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010080int mbedtls_sha256_starts_ret( 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 );
83 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000084
Paul Bakker5121ce52009-01-03 21:22:43 +000085 ctx->total[0] = 0;
86 ctx->total[1] = 0;
87
88 if( is224 == 0 )
89 {
90 /* SHA-256 */
91 ctx->state[0] = 0x6A09E667;
92 ctx->state[1] = 0xBB67AE85;
93 ctx->state[2] = 0x3C6EF372;
94 ctx->state[3] = 0xA54FF53A;
95 ctx->state[4] = 0x510E527F;
96 ctx->state[5] = 0x9B05688C;
97 ctx->state[6] = 0x1F83D9AB;
98 ctx->state[7] = 0x5BE0CD19;
99 }
100 else
101 {
102 /* SHA-224 */
103 ctx->state[0] = 0xC1059ED8;
104 ctx->state[1] = 0x367CD507;
105 ctx->state[2] = 0x3070DD17;
106 ctx->state[3] = 0xF70E5939;
107 ctx->state[4] = 0xFFC00B31;
108 ctx->state[5] = 0x68581511;
109 ctx->state[6] = 0x64F98FA7;
110 ctx->state[7] = 0xBEFA4FA4;
111 }
112
113 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100114
115 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000116}
117
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200118#if !defined(MBEDTLS_DEPRECATED_REMOVED)
119void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
120 int is224 )
121{
122 mbedtls_sha256_starts_ret( ctx, is224 );
123}
124#endif
125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200127static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000128{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200129 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
130 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
131 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
132 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
133 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
134 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
135 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
136 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
137 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
138 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
139 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
140 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
141 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
142 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
143 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
144 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
145};
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
Hanno Becker1eeca412018-10-15 12:01:35 +0100147#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
148#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000149
150#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
151#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
152
153#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
154#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
155
Hanno Becker1eeca412018-10-15 12:01:35 +0100156#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
157#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200159#define R(t) \
160 ( \
161 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
162 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100163 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200165#define P(a,b,c,d,e,f,g,h,x,K) \
166 do \
167 { \
168 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
169 local.temp2 = S2(a) + F0((a),(b),(c)); \
170 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100171 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000172
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100173int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100174 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200175{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200176 struct
177 {
178 uint32_t temp1, temp2, W[64];
179 uint32_t A[8];
180 } local;
181
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200182 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000183
Hanno Becker8d215e72018-12-18 17:53:21 +0000184 SHA256_VALIDATE_RET( ctx != NULL );
185 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000186
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200187 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200188 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200189
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200190#if defined(MBEDTLS_SHA256_SMALLER)
191 for( i = 0; i < 64; i++ )
192 {
193 if( i < 16 )
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100194 MBEDTLS_GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200195 else
196 R( i );
197
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200198 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
199 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200200
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200201 local.temp1 = local.A[7]; local.A[7] = local.A[6];
202 local.A[6] = local.A[5]; local.A[5] = local.A[4];
203 local.A[4] = local.A[3]; local.A[3] = local.A[2];
204 local.A[2] = local.A[1]; local.A[1] = local.A[0];
205 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200206 }
207#else /* MBEDTLS_SHA256_SMALLER */
208 for( i = 0; i < 16; i++ )
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100209 MBEDTLS_GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200210
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200211 for( i = 0; i < 16; i += 8 )
212 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200213 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
214 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
215 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
216 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
217 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
218 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
219 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
220 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
221 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
222 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
223 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
224 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
225 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
226 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
227 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
228 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 +0200229 }
230
231 for( i = 16; i < 64; i += 8 )
232 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200233 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
234 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
235 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
236 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
237 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
238 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
239 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
240 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
241 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
242 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
243 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
244 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
245 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
246 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
247 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
248 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200249 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200250#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200251
252 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200253 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100254
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200255 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200256 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100257
258 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000259}
Jaeden Amero041039f2018-02-19 15:28:08 +0000260
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200261#if !defined(MBEDTLS_DEPRECATED_REMOVED)
262void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
263 const unsigned char data[64] )
264{
265 mbedtls_internal_sha256_process( ctx, data );
266}
267#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000269
270/*
271 * SHA-256 process buffer
272 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100273int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100274 const unsigned char *input,
275 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000276{
Janos Follath24eed8d2019-11-22 13:21:35 +0000277 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000278 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000279 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000280
Hanno Becker8d215e72018-12-18 17:53:21 +0000281 SHA256_VALIDATE_RET( ctx != NULL );
282 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000283
Brian White12895d12014-04-11 11:29:42 -0400284 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100285 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000286
287 left = ctx->total[0] & 0x3F;
288 fill = 64 - left;
289
Paul Bakker5c2364c2012-10-01 14:41:15 +0000290 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 ctx->total[0] &= 0xFFFFFFFF;
292
Paul Bakker5c2364c2012-10-01 14:41:15 +0000293 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 ctx->total[1]++;
295
296 if( left && ilen >= fill )
297 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200298 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100299
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100300 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100301 return( ret );
302
Paul Bakker5121ce52009-01-03 21:22:43 +0000303 input += fill;
304 ilen -= fill;
305 left = 0;
306 }
307
308 while( ilen >= 64 )
309 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100310 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100311 return( ret );
312
Paul Bakker5121ce52009-01-03 21:22:43 +0000313 input += 64;
314 ilen -= 64;
315 }
316
317 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200318 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100319
320 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321}
322
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200323#if !defined(MBEDTLS_DEPRECATED_REMOVED)
324void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
325 const unsigned char *input,
326 size_t ilen )
327{
328 mbedtls_sha256_update_ret( ctx, input, ilen );
329}
330#endif
331
Paul Bakker5121ce52009-01-03 21:22:43 +0000332/*
333 * SHA-256 final digest
334 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100335int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100336 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000337{
Janos Follath24eed8d2019-11-22 13:21:35 +0000338 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200339 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000340 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
Hanno Becker8d215e72018-12-18 17:53:21 +0000342 SHA256_VALIDATE_RET( ctx != NULL );
343 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000344
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200345 /*
346 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
347 */
348 used = ctx->total[0] & 0x3F;
349
350 ctx->buffer[used++] = 0x80;
351
352 if( used <= 56 )
353 {
354 /* Enough room for padding + length in current block */
355 memset( ctx->buffer + used, 0, 56 - used );
356 }
357 else
358 {
359 /* We'll need an extra block */
360 memset( ctx->buffer + used, 0, 64 - used );
361
362 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
363 return( ret );
364
365 memset( ctx->buffer, 0, 56 );
366 }
367
368 /*
369 * Add message length
370 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000371 high = ( ctx->total[0] >> 29 )
372 | ( ctx->total[1] << 3 );
373 low = ( ctx->total[0] << 3 );
374
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100375 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
376 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000377
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200378 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100379 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100380
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200381 /*
382 * Output final state
383 */
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100384 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
385 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
386 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
387 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
388 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
389 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
390 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
392 if( ctx->is224 == 0 )
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100393 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100394
395 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000396}
397
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200398#if !defined(MBEDTLS_DEPRECATED_REMOVED)
399void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
400 unsigned char output[32] )
401{
402 mbedtls_sha256_finish_ret( ctx, output );
403}
404#endif
405
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200407
Paul Bakker5121ce52009-01-03 21:22:43 +0000408/*
409 * output = SHA-256( input buffer )
410 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100411int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100412 size_t ilen,
413 unsigned char output[32],
414 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000415{
Janos Follath24eed8d2019-11-22 13:21:35 +0000416 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
Hanno Becker8d215e72018-12-18 17:53:21 +0000419 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
420 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
421 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100424
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100425 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100426 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100427
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100428 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100429 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100430
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100431 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100432 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100433
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100434exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100436
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100437 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438}
439
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200440#if !defined(MBEDTLS_DEPRECATED_REMOVED)
441void mbedtls_sha256( const unsigned char *input,
442 size_t ilen,
443 unsigned char output[32],
444 int is224 )
445{
446 mbedtls_sha256_ret( input, ilen, output, is224 );
447}
448#endif
449
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000451/*
452 * FIPS-180-2 test vectors
453 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000454static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000455{
456 { "abc" },
457 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
458 { "" }
459};
460
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100461static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000462{
463 3, 56, 1000
464};
465
Paul Bakker9e36f042013-06-30 14:34:05 +0200466static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000467{
468 /*
469 * SHA-224 test vectors
470 */
471 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
472 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
473 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
474 0xE3, 0x6C, 0x9D, 0xA7 },
475 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
476 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
477 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
478 0x52, 0x52, 0x25, 0x25 },
479 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
480 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
481 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
482 0x4E, 0xE7, 0xAD, 0x67 },
483
484 /*
485 * SHA-256 test vectors
486 */
487 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
488 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
489 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
490 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
491 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
492 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
493 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
494 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
495 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
496 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
497 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
498 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
499};
500
501/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000502 * Checkup routine
503 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000505{
Paul Bakker5b4af392014-06-26 12:09:34 +0200506 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500507 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200508 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
Russ Butlerbb83b422016-10-12 17:36:50 -0500511 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
512 if( NULL == buf )
513 {
514 if( verbose != 0 )
515 mbedtls_printf( "Buffer allocation failed\n" );
516
517 return( 1 );
518 }
519
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200521
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 for( i = 0; i < 6; i++ )
523 {
524 j = i % 3;
525 k = i < 3;
526
527 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100530 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100531 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
533 if( j == 2 )
534 {
535 memset( buf, 'a', buflen = 1000 );
536
537 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100538 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100539 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100540 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100541 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100542 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100543
Paul Bakker5121ce52009-01-03 21:22:43 +0000544 }
545 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100546 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100547 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100548 sha256_test_buflen[j] );
549 if( ret != 0 )
550 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100551 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100553 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100554 goto fail;
555
Paul Bakker5121ce52009-01-03 21:22:43 +0000556
Paul Bakker9e36f042013-06-30 14:34:05 +0200557 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100558 {
559 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100560 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100561 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
563 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000565 }
566
567 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100570 goto exit;
571
572fail:
573 if( verbose != 0 )
574 mbedtls_printf( "failed\n" );
575
Paul Bakker5b4af392014-06-26 12:09:34 +0200576exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500578 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200579
580 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000581}
582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585#endif /* MBEDTLS_SHA256_C */