blob: 6ec6da296adf6f810bd52f3f5a321288796d531b [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
Paul Bakker5121ce52009-01-03 21:22:43 +000053/*
54 * 32-bit integer manipulation macros (big endian)
55 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000056#ifndef GET_UINT32_BE
57#define GET_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020058do { \
Paul Bakker5c2364c2012-10-01 14:41:15 +000059 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
60 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
61 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
62 | ( (uint32_t) (b)[(i) + 3] ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020063} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000064#endif
65
Paul Bakker5c2364c2012-10-01 14:41:15 +000066#ifndef PUT_UINT32_BE
67#define PUT_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020068do { \
Paul Bakker5121ce52009-01-03 21:22:43 +000069 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
70 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
71 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
72 (b)[(i) + 3] = (unsigned char) ( (n) ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020073} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000074#endif
75
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020077{
Hanno Becker8d215e72018-12-18 17:53:21 +000078 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000079
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020081}
82
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020084{
85 if( ctx == NULL )
86 return;
87
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050088 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020089}
90
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020091void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
92 const mbedtls_sha256_context *src )
93{
Hanno Becker8d215e72018-12-18 17:53:21 +000094 SHA256_VALIDATE( dst != NULL );
95 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000096
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020097 *dst = *src;
98}
99
Paul Bakker5121ce52009-01-03 21:22:43 +0000100/*
101 * SHA-256 context setup
102 */
TRodziewicz26371e42021-06-08 16:45:41 +0200103int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
Hanno Becker8d215e72018-12-18 17:53:21 +0000105 SHA256_VALIDATE_RET( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000106
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200107#if defined(MBEDTLS_SHA224_C)
108 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
109#else
110 SHA256_VALIDATE_RET( is224 == 0 );
111#endif
112
Paul Bakker5121ce52009-01-03 21:22:43 +0000113 ctx->total[0] = 0;
114 ctx->total[1] = 0;
115
116 if( is224 == 0 )
117 {
118 /* SHA-256 */
119 ctx->state[0] = 0x6A09E667;
120 ctx->state[1] = 0xBB67AE85;
121 ctx->state[2] = 0x3C6EF372;
122 ctx->state[3] = 0xA54FF53A;
123 ctx->state[4] = 0x510E527F;
124 ctx->state[5] = 0x9B05688C;
125 ctx->state[6] = 0x1F83D9AB;
126 ctx->state[7] = 0x5BE0CD19;
127 }
128 else
129 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200130#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000131 /* SHA-224 */
132 ctx->state[0] = 0xC1059ED8;
133 ctx->state[1] = 0x367CD507;
134 ctx->state[2] = 0x3070DD17;
135 ctx->state[3] = 0xF70E5939;
136 ctx->state[4] = 0xFFC00B31;
137 ctx->state[5] = 0x68581511;
138 ctx->state[6] = 0x64F98FA7;
139 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200140#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000141 }
142
143 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100144
145 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000146}
147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200149static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000150{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200151 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
152 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
153 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
154 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
155 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
156 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
157 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
158 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
159 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
160 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
161 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
162 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
163 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
164 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
165 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
166 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
167};
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
Hanno Becker1eeca412018-10-15 12:01:35 +0100169#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
170#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000171
172#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
173#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
174
175#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
176#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
177
Hanno Becker1eeca412018-10-15 12:01:35 +0100178#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
179#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000180
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200181#define R(t) \
182 ( \
183 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
184 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100185 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000186
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200187#define P(a,b,c,d,e,f,g,h,x,K) \
188 do \
189 { \
190 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
191 local.temp2 = S2(a) + F0((a),(b),(c)); \
192 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100193 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100195int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100196 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200197{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200198 struct
199 {
200 uint32_t temp1, temp2, W[64];
201 uint32_t A[8];
202 } local;
203
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200204 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000205
Hanno Becker8d215e72018-12-18 17:53:21 +0000206 SHA256_VALIDATE_RET( ctx != NULL );
207 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000208
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200209 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200210 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200211
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200212#if defined(MBEDTLS_SHA256_SMALLER)
213 for( i = 0; i < 64; i++ )
214 {
215 if( i < 16 )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200216 GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200217 else
218 R( i );
219
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200220 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
221 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200222
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200223 local.temp1 = local.A[7]; local.A[7] = local.A[6];
224 local.A[6] = local.A[5]; local.A[5] = local.A[4];
225 local.A[4] = local.A[3]; local.A[3] = local.A[2];
226 local.A[2] = local.A[1]; local.A[1] = local.A[0];
227 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200228 }
229#else /* MBEDTLS_SHA256_SMALLER */
230 for( i = 0; i < 16; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200231 GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200232
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200233 for( i = 0; i < 16; i += 8 )
234 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200235 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
236 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
237 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
238 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
239 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
240 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
241 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
242 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
243 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
244 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
245 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
246 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
247 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
248 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
249 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
250 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 +0200251 }
252
253 for( i = 16; i < 64; i += 8 )
254 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200255 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
256 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
257 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
258 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
259 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
260 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
261 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
262 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
263 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
264 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
265 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
266 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
267 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
268 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
269 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
270 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200271 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200272#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200273
274 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200275 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100276
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200277 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200278 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100279
280 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000281}
Jaeden Amero041039f2018-02-19 15:28:08 +0000282
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000284
285/*
286 * SHA-256 process buffer
287 */
TRodziewicz26371e42021-06-08 16:45:41 +0200288int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100289 const unsigned char *input,
290 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000291{
Janos Follath24eed8d2019-11-22 13:21:35 +0000292 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000293 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000294 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000295
Hanno Becker8d215e72018-12-18 17:53:21 +0000296 SHA256_VALIDATE_RET( ctx != NULL );
297 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000298
Brian White12895d12014-04-11 11:29:42 -0400299 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100300 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
302 left = ctx->total[0] & 0x3F;
303 fill = 64 - left;
304
Paul Bakker5c2364c2012-10-01 14:41:15 +0000305 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000306 ctx->total[0] &= 0xFFFFFFFF;
307
Paul Bakker5c2364c2012-10-01 14:41:15 +0000308 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000309 ctx->total[1]++;
310
311 if( left && ilen >= fill )
312 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200313 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100314
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100315 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100316 return( ret );
317
Paul Bakker5121ce52009-01-03 21:22:43 +0000318 input += fill;
319 ilen -= fill;
320 left = 0;
321 }
322
323 while( ilen >= 64 )
324 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100325 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100326 return( ret );
327
Paul Bakker5121ce52009-01-03 21:22:43 +0000328 input += 64;
329 ilen -= 64;
330 }
331
332 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200333 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100334
335 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000336}
337
Paul Bakker5121ce52009-01-03 21:22:43 +0000338/*
339 * SHA-256 final digest
340 */
TRodziewicz26371e42021-06-08 16:45:41 +0200341int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200342 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000343{
Janos Follath24eed8d2019-11-22 13:21:35 +0000344 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200345 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
Hanno Becker8d215e72018-12-18 17:53:21 +0000348 SHA256_VALIDATE_RET( ctx != NULL );
349 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000350
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200351 /*
352 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
353 */
354 used = ctx->total[0] & 0x3F;
355
356 ctx->buffer[used++] = 0x80;
357
358 if( used <= 56 )
359 {
360 /* Enough room for padding + length in current block */
361 memset( ctx->buffer + used, 0, 56 - used );
362 }
363 else
364 {
365 /* We'll need an extra block */
366 memset( ctx->buffer + used, 0, 64 - used );
367
368 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
369 return( ret );
370
371 memset( ctx->buffer, 0, 56 );
372 }
373
374 /*
375 * Add message length
376 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000377 high = ( ctx->total[0] >> 29 )
378 | ( ctx->total[1] << 3 );
379 low = ( ctx->total[0] << 3 );
380
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200381 PUT_UINT32_BE( high, ctx->buffer, 56 );
382 PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200384 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100385 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100386
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200387 /*
388 * Output final state
389 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000390 PUT_UINT32_BE( ctx->state[0], output, 0 );
391 PUT_UINT32_BE( ctx->state[1], output, 4 );
392 PUT_UINT32_BE( ctx->state[2], output, 8 );
393 PUT_UINT32_BE( ctx->state[3], output, 12 );
394 PUT_UINT32_BE( ctx->state[4], output, 16 );
395 PUT_UINT32_BE( ctx->state[5], output, 20 );
396 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200398#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200400#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000401 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100402
403 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000404}
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 */
TRodziewicz26371e42021-06-08 16:45:41 +0200411int mbedtls_sha256( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100412 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200413 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100414 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
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200419#if defined(MBEDTLS_SHA224_C)
Hanno Becker8d215e72018-12-18 17:53:21 +0000420 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200421#else
422 SHA256_VALIDATE_RET( is224 == 0 );
423#endif
424
Hanno Becker8d215e72018-12-18 17:53:21 +0000425 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
426 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000427
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100429
TRodziewicz26371e42021-06-08 16:45:41 +0200430 if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100431 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100432
TRodziewicz26371e42021-06-08 16:45:41 +0200433 if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100434 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100435
TRodziewicz26371e42021-06-08 16:45:41 +0200436 if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100437 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100438
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100439exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100441
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100442 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000443}
444
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000446/*
447 * FIPS-180-2 test vectors
448 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000449static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000450{
451 { "abc" },
452 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
453 { "" }
454};
455
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100456static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000457{
458 3, 56, 1000
459};
460
Paul Bakker9e36f042013-06-30 14:34:05 +0200461static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000462{
463 /*
464 * SHA-224 test vectors
465 */
466 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
467 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
468 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
469 0xE3, 0x6C, 0x9D, 0xA7 },
470 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
471 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
472 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
473 0x52, 0x52, 0x25, 0x25 },
474 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
475 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
476 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
477 0x4E, 0xE7, 0xAD, 0x67 },
478
479 /*
480 * SHA-256 test vectors
481 */
482 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
483 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
484 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
485 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
486 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
487 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
488 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
489 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
490 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
491 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
492 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
493 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
494};
495
496/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000497 * Checkup routine
498 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000500{
Paul Bakker5b4af392014-06-26 12:09:34 +0200501 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500502 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200503 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000505
Russ Butlerbb83b422016-10-12 17:36:50 -0500506 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
507 if( NULL == buf )
508 {
509 if( verbose != 0 )
510 mbedtls_printf( "Buffer allocation failed\n" );
511
512 return( 1 );
513 }
514
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200516
Paul Bakker5121ce52009-01-03 21:22:43 +0000517 for( i = 0; i < 6; i++ )
518 {
519 j = i % 3;
520 k = i < 3;
521
522 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
TRodziewicz26371e42021-06-08 16:45:41 +0200525 if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100526 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
528 if( j == 2 )
529 {
530 memset( buf, 'a', buflen = 1000 );
531
532 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100533 {
TRodziewicz26371e42021-06-08 16:45:41 +0200534 ret = mbedtls_sha256_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100535 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100536 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100537 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100538
Paul Bakker5121ce52009-01-03 21:22:43 +0000539 }
540 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100541 {
TRodziewicz26371e42021-06-08 16:45:41 +0200542 ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100543 sha256_test_buflen[j] );
544 if( ret != 0 )
545 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100546 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000547
TRodziewicz26371e42021-06-08 16:45:41 +0200548 if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100549 goto fail;
550
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
Paul Bakker9e36f042013-06-30 14:34:05 +0200552 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100553 {
554 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100555 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100556 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
558 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560 }
561
562 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100565 goto exit;
566
567fail:
568 if( verbose != 0 )
569 mbedtls_printf( "failed\n" );
570
Paul Bakker5b4af392014-06-26 12:09:34 +0200571exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500573 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200574
575 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000576}
577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580#endif /* MBEDTLS_SHA256_C */