blob: 6f1306ee6606dc884899d0552373eb5687957a53 [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é-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010036
Hanno Becker2f6de422018-12-20 10:22:32 +000037#define SHA256_VALIDATE_RET(cond) \
38 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
39#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
40
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020041#if !defined(MBEDTLS_SHA256_ALT)
42
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020044{
Hanno Becker8d215e72018-12-18 17:53:21 +000045 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000046
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020048}
49
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020051{
52 if( ctx == NULL )
53 return;
54
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050055 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020056}
57
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020058void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
59 const mbedtls_sha256_context *src )
60{
Hanno Becker8d215e72018-12-18 17:53:21 +000061 SHA256_VALIDATE( dst != NULL );
62 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000063
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020064 *dst = *src;
65}
66
Paul Bakker5121ce52009-01-03 21:22:43 +000067/*
68 * SHA-256 context setup
69 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010070int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +000071{
Hanno Becker8d215e72018-12-18 17:53:21 +000072 SHA256_VALIDATE_RET( ctx != NULL );
73 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000074
Paul Bakker5121ce52009-01-03 21:22:43 +000075 ctx->total[0] = 0;
76 ctx->total[1] = 0;
77
78 if( is224 == 0 )
79 {
80 /* SHA-256 */
81 ctx->state[0] = 0x6A09E667;
82 ctx->state[1] = 0xBB67AE85;
83 ctx->state[2] = 0x3C6EF372;
84 ctx->state[3] = 0xA54FF53A;
85 ctx->state[4] = 0x510E527F;
86 ctx->state[5] = 0x9B05688C;
87 ctx->state[6] = 0x1F83D9AB;
88 ctx->state[7] = 0x5BE0CD19;
89 }
90 else
91 {
92 /* SHA-224 */
93 ctx->state[0] = 0xC1059ED8;
94 ctx->state[1] = 0x367CD507;
95 ctx->state[2] = 0x3070DD17;
96 ctx->state[3] = 0xF70E5939;
97 ctx->state[4] = 0xFFC00B31;
98 ctx->state[5] = 0x68581511;
99 ctx->state[6] = 0x64F98FA7;
100 ctx->state[7] = 0xBEFA4FA4;
101 }
102
103 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100104
105 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000106}
107
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200108#if !defined(MBEDTLS_DEPRECATED_REMOVED)
109void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
110 int is224 )
111{
112 mbedtls_sha256_starts_ret( ctx, is224 );
113}
114#endif
115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200117static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000118{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200119 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
120 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
121 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
122 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
123 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
124 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
125 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
126 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
127 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
128 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
129 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
130 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
131 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
132 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
133 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
134 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
135};
Paul Bakker5121ce52009-01-03 21:22:43 +0000136
Hanno Becker1eeca412018-10-15 12:01:35 +0100137#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
138#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000139
140#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
141#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
142
143#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
144#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
145
Hanno Becker1eeca412018-10-15 12:01:35 +0100146#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
147#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000148
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200149#define R(t) \
150 ( \
151 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
152 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100153 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000154
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200155#define P(a,b,c,d,e,f,g,h,x,K) \
156 do \
157 { \
158 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
159 local.temp2 = S2(a) + F0((a),(b),(c)); \
160 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100161 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100163int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100164 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200165{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200166 struct
167 {
168 uint32_t temp1, temp2, W[64];
169 uint32_t A[8];
170 } local;
171
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200172 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000173
Hanno Becker8d215e72018-12-18 17:53:21 +0000174 SHA256_VALIDATE_RET( ctx != NULL );
175 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000176
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200177 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200178 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200179
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200180#if defined(MBEDTLS_SHA256_SMALLER)
181 for( i = 0; i < 64; i++ )
182 {
183 if( i < 16 )
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100184 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200185 else
186 R( i );
187
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200188 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
189 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200190
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200191 local.temp1 = local.A[7]; local.A[7] = local.A[6];
192 local.A[6] = local.A[5]; local.A[5] = local.A[4];
193 local.A[4] = local.A[3]; local.A[3] = local.A[2];
194 local.A[2] = local.A[1]; local.A[1] = local.A[0];
195 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200196 }
197#else /* MBEDTLS_SHA256_SMALLER */
198 for( i = 0; i < 16; i++ )
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100199 local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200200
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200201 for( i = 0; i < 16; i += 8 )
202 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200203 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
204 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
205 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
206 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
207 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
208 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
209 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
210 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
211 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
212 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
213 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
214 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
215 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
216 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
217 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
218 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 +0200219 }
220
221 for( i = 16; i < 64; i += 8 )
222 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200223 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
224 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
225 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
226 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
227 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
228 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
229 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
230 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
231 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
232 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
233 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
234 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
235 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
236 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
237 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
238 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200239 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200240#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200241
242 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200243 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100244
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200245 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200246 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100247
248 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000249}
Jaeden Amero041039f2018-02-19 15:28:08 +0000250
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200251#if !defined(MBEDTLS_DEPRECATED_REMOVED)
252void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
253 const unsigned char data[64] )
254{
255 mbedtls_internal_sha256_process( ctx, data );
256}
257#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000259
260/*
261 * SHA-256 process buffer
262 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100263int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100264 const unsigned char *input,
265 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000266{
Janos Follath24eed8d2019-11-22 13:21:35 +0000267 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000268 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000269 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000270
Hanno Becker8d215e72018-12-18 17:53:21 +0000271 SHA256_VALIDATE_RET( ctx != NULL );
272 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000273
Brian White12895d12014-04-11 11:29:42 -0400274 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100275 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
277 left = ctx->total[0] & 0x3F;
278 fill = 64 - left;
279
Paul Bakker5c2364c2012-10-01 14:41:15 +0000280 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000281 ctx->total[0] &= 0xFFFFFFFF;
282
Paul Bakker5c2364c2012-10-01 14:41:15 +0000283 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 ctx->total[1]++;
285
286 if( left && ilen >= fill )
287 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200288 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100289
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100290 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100291 return( ret );
292
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 input += fill;
294 ilen -= fill;
295 left = 0;
296 }
297
298 while( ilen >= 64 )
299 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100300 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100301 return( ret );
302
Paul Bakker5121ce52009-01-03 21:22:43 +0000303 input += 64;
304 ilen -= 64;
305 }
306
307 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200308 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100309
310 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311}
312
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200313#if !defined(MBEDTLS_DEPRECATED_REMOVED)
314void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
315 const unsigned char *input,
316 size_t ilen )
317{
318 mbedtls_sha256_update_ret( ctx, input, ilen );
319}
320#endif
321
Paul Bakker5121ce52009-01-03 21:22:43 +0000322/*
323 * SHA-256 final digest
324 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100325int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100326 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000327{
Janos Follath24eed8d2019-11-22 13:21:35 +0000328 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200329 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000330 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000331
Hanno Becker8d215e72018-12-18 17:53:21 +0000332 SHA256_VALIDATE_RET( ctx != NULL );
333 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000334
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200335 /*
336 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
337 */
338 used = ctx->total[0] & 0x3F;
339
340 ctx->buffer[used++] = 0x80;
341
342 if( used <= 56 )
343 {
344 /* Enough room for padding + length in current block */
345 memset( ctx->buffer + used, 0, 56 - used );
346 }
347 else
348 {
349 /* We'll need an extra block */
350 memset( ctx->buffer + used, 0, 64 - used );
351
352 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
353 return( ret );
354
355 memset( ctx->buffer, 0, 56 );
356 }
357
358 /*
359 * Add message length
360 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000361 high = ( ctx->total[0] >> 29 )
362 | ( ctx->total[1] << 3 );
363 low = ( ctx->total[0] << 3 );
364
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100365 MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
366 MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000367
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200368 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100369 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100370
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200371 /*
372 * Output final state
373 */
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100374 MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
375 MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
376 MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
377 MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
378 MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
379 MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
380 MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
382 if( ctx->is224 == 0 )
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100383 MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100384
385 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000386}
387
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200388#if !defined(MBEDTLS_DEPRECATED_REMOVED)
389void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
390 unsigned char output[32] )
391{
392 mbedtls_sha256_finish_ret( ctx, output );
393}
394#endif
395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200397
Paul Bakker5121ce52009-01-03 21:22:43 +0000398/*
399 * output = SHA-256( input buffer )
400 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100401int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100402 size_t ilen,
403 unsigned char output[32],
404 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000405{
Janos Follath24eed8d2019-11-22 13:21:35 +0000406 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Hanno Becker8d215e72018-12-18 17:53:21 +0000409 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
410 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
411 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000412
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100414
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100415 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100416 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100417
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100418 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100419 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100420
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100421 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100422 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100423
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100424exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100426
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100427 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000428}
429
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200430#if !defined(MBEDTLS_DEPRECATED_REMOVED)
431void mbedtls_sha256( const unsigned char *input,
432 size_t ilen,
433 unsigned char output[32],
434 int is224 )
435{
436 mbedtls_sha256_ret( input, ilen, output, is224 );
437}
438#endif
439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000441/*
442 * FIPS-180-2 test vectors
443 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000444static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000445{
446 { "abc" },
447 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
448 { "" }
449};
450
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100451static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000452{
453 3, 56, 1000
454};
455
Paul Bakker9e36f042013-06-30 14:34:05 +0200456static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000457{
458 /*
459 * SHA-224 test vectors
460 */
461 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
462 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
463 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
464 0xE3, 0x6C, 0x9D, 0xA7 },
465 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
466 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
467 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
468 0x52, 0x52, 0x25, 0x25 },
469 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
470 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
471 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
472 0x4E, 0xE7, 0xAD, 0x67 },
473
474 /*
475 * SHA-256 test vectors
476 */
477 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
478 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
479 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
480 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
481 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
482 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
483 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
484 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
485 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
486 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
487 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
488 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
489};
490
491/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000492 * Checkup routine
493 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000495{
Paul Bakker5b4af392014-06-26 12:09:34 +0200496 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500497 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200498 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
Russ Butlerbb83b422016-10-12 17:36:50 -0500501 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
502 if( NULL == buf )
503 {
504 if( verbose != 0 )
505 mbedtls_printf( "Buffer allocation failed\n" );
506
507 return( 1 );
508 }
509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200511
Paul Bakker5121ce52009-01-03 21:22:43 +0000512 for( i = 0; i < 6; i++ )
513 {
514 j = i % 3;
515 k = i < 3;
516
517 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000519
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100520 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100521 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000522
523 if( j == 2 )
524 {
525 memset( buf, 'a', buflen = 1000 );
526
527 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100528 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100529 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100530 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100531 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100532 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100533
Paul Bakker5121ce52009-01-03 21:22:43 +0000534 }
535 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100536 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100537 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100538 sha256_test_buflen[j] );
539 if( ret != 0 )
540 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100541 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000542
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100543 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100544 goto fail;
545
Paul Bakker5121ce52009-01-03 21:22:43 +0000546
Paul Bakker9e36f042013-06-30 14:34:05 +0200547 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100548 {
549 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100550 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100551 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
553 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000555 }
556
557 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000559
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100560 goto exit;
561
562fail:
563 if( verbose != 0 )
564 mbedtls_printf( "failed\n" );
565
Paul Bakker5b4af392014-06-26 12:09:34 +0200566exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500568 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200569
570 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571}
572
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575#endif /* MBEDTLS_SHA256_C */