blob: 264d33ae9aa85341b37d1564e49b558ec64f2a6c [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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100103int mbedtls_sha256_starts_ret( 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 );
106 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000107
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200108#if defined(MBEDTLS_SHA224_C)
109 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
110#else
111 SHA256_VALIDATE_RET( is224 == 0 );
112#endif
113
Paul Bakker5121ce52009-01-03 21:22:43 +0000114 ctx->total[0] = 0;
115 ctx->total[1] = 0;
116
117 if( is224 == 0 )
118 {
119 /* SHA-256 */
120 ctx->state[0] = 0x6A09E667;
121 ctx->state[1] = 0xBB67AE85;
122 ctx->state[2] = 0x3C6EF372;
123 ctx->state[3] = 0xA54FF53A;
124 ctx->state[4] = 0x510E527F;
125 ctx->state[5] = 0x9B05688C;
126 ctx->state[6] = 0x1F83D9AB;
127 ctx->state[7] = 0x5BE0CD19;
128 }
129 else
130 {
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200131#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000132 /* SHA-224 */
133 ctx->state[0] = 0xC1059ED8;
134 ctx->state[1] = 0x367CD507;
135 ctx->state[2] = 0x3070DD17;
136 ctx->state[3] = 0xF70E5939;
137 ctx->state[4] = 0xFFC00B31;
138 ctx->state[5] = 0x68581511;
139 ctx->state[6] = 0x64F98FA7;
140 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200141#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000142 }
143
144 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100145
146 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000147}
148
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200150static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000151{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200152 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
153 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
154 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
155 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
156 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
157 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
158 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
159 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
160 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
161 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
162 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
163 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
164 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
165 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
166 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
167 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
168};
Paul Bakker5121ce52009-01-03 21:22:43 +0000169
Hanno Becker1eeca412018-10-15 12:01:35 +0100170#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
171#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000172
173#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
174#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
175
176#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
177#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
178
Hanno Becker1eeca412018-10-15 12:01:35 +0100179#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
180#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000181
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200182#define R(t) \
183 ( \
184 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
185 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100186 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000187
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200188#define P(a,b,c,d,e,f,g,h,x,K) \
189 do \
190 { \
191 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
192 local.temp2 = S2(a) + F0((a),(b),(c)); \
193 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100194 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000195
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100196int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100197 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200198{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200199 struct
200 {
201 uint32_t temp1, temp2, W[64];
202 uint32_t A[8];
203 } local;
204
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200205 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000206
Hanno Becker8d215e72018-12-18 17:53:21 +0000207 SHA256_VALIDATE_RET( ctx != NULL );
208 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000209
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200210 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200211 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200212
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200213#if defined(MBEDTLS_SHA256_SMALLER)
214 for( i = 0; i < 64; i++ )
215 {
216 if( i < 16 )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200217 GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200218 else
219 R( i );
220
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200221 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
222 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200223
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200224 local.temp1 = local.A[7]; local.A[7] = local.A[6];
225 local.A[6] = local.A[5]; local.A[5] = local.A[4];
226 local.A[4] = local.A[3]; local.A[3] = local.A[2];
227 local.A[2] = local.A[1]; local.A[1] = local.A[0];
228 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200229 }
230#else /* MBEDTLS_SHA256_SMALLER */
231 for( i = 0; i < 16; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200232 GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200233
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200234 for( i = 0; i < 16; i += 8 )
235 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200236 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
237 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
238 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
239 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
240 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
241 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
242 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
243 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
244 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
245 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
246 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
247 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
248 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
249 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
250 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
251 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 +0200252 }
253
254 for( i = 16; i < 64; i += 8 )
255 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200256 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
257 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
258 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
259 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
260 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
261 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
262 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
263 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
264 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
265 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
266 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
267 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
268 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
269 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
270 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
271 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200272 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200273#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200274
275 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200276 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100277
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200278 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200279 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100280
281 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000282}
Jaeden Amero041039f2018-02-19 15:28:08 +0000283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000285
286/*
287 * SHA-256 process buffer
288 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100289int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100290 const unsigned char *input,
291 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000292{
Janos Follath24eed8d2019-11-22 13:21:35 +0000293 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000294 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000295 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
Hanno Becker8d215e72018-12-18 17:53:21 +0000297 SHA256_VALIDATE_RET( ctx != NULL );
298 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000299
Brian White12895d12014-04-11 11:29:42 -0400300 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100301 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
303 left = ctx->total[0] & 0x3F;
304 fill = 64 - left;
305
Paul Bakker5c2364c2012-10-01 14:41:15 +0000306 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000307 ctx->total[0] &= 0xFFFFFFFF;
308
Paul Bakker5c2364c2012-10-01 14:41:15 +0000309 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 ctx->total[1]++;
311
312 if( left && ilen >= fill )
313 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200314 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100315
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100316 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100317 return( ret );
318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 input += fill;
320 ilen -= fill;
321 left = 0;
322 }
323
324 while( ilen >= 64 )
325 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100326 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100327 return( ret );
328
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 input += 64;
330 ilen -= 64;
331 }
332
333 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200334 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100335
336 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337}
338
Paul Bakker5121ce52009-01-03 21:22:43 +0000339/*
340 * SHA-256 final digest
341 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100342int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100343 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000344{
Janos Follath24eed8d2019-11-22 13:21:35 +0000345 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200346 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
Hanno Becker8d215e72018-12-18 17:53:21 +0000349 SHA256_VALIDATE_RET( ctx != NULL );
350 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000351
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200352 /*
353 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
354 */
355 used = ctx->total[0] & 0x3F;
356
357 ctx->buffer[used++] = 0x80;
358
359 if( used <= 56 )
360 {
361 /* Enough room for padding + length in current block */
362 memset( ctx->buffer + used, 0, 56 - used );
363 }
364 else
365 {
366 /* We'll need an extra block */
367 memset( ctx->buffer + used, 0, 64 - used );
368
369 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
370 return( ret );
371
372 memset( ctx->buffer, 0, 56 );
373 }
374
375 /*
376 * Add message length
377 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 high = ( ctx->total[0] >> 29 )
379 | ( ctx->total[1] << 3 );
380 low = ( ctx->total[0] << 3 );
381
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200382 PUT_UINT32_BE( high, ctx->buffer, 56 );
383 PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200385 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100386 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100387
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200388 /*
389 * Output final state
390 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000391 PUT_UINT32_BE( ctx->state[0], output, 0 );
392 PUT_UINT32_BE( ctx->state[1], output, 4 );
393 PUT_UINT32_BE( ctx->state[2], output, 8 );
394 PUT_UINT32_BE( ctx->state[3], output, 12 );
395 PUT_UINT32_BE( ctx->state[4], output, 16 );
396 PUT_UINT32_BE( ctx->state[5], output, 20 );
397 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200399#if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000400 if( ctx->is224 == 0 )
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200401#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000402 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100403
404 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405}
406
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200408
Paul Bakker5121ce52009-01-03 21:22:43 +0000409/*
410 * output = SHA-256( input buffer )
411 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100412int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100413 size_t ilen,
414 unsigned char output[32],
415 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000416{
Janos Follath24eed8d2019-11-22 13:21:35 +0000417 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200420#if defined(MBEDTLS_SHA224_C)
Hanno Becker8d215e72018-12-18 17:53:21 +0000421 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200422#else
423 SHA256_VALIDATE_RET( is224 == 0 );
424#endif
425
Hanno Becker8d215e72018-12-18 17:53:21 +0000426 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
427 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100430
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100431 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100432 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100433
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100434 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100435 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100436
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100437 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100438 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100439
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100440exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100442
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100443 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000444}
445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000447/*
448 * FIPS-180-2 test vectors
449 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000450static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000451{
452 { "abc" },
453 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
454 { "" }
455};
456
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100457static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000458{
459 3, 56, 1000
460};
461
Paul Bakker9e36f042013-06-30 14:34:05 +0200462static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000463{
464 /*
465 * SHA-224 test vectors
466 */
467 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
468 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
469 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
470 0xE3, 0x6C, 0x9D, 0xA7 },
471 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
472 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
473 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
474 0x52, 0x52, 0x25, 0x25 },
475 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
476 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
477 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
478 0x4E, 0xE7, 0xAD, 0x67 },
479
480 /*
481 * SHA-256 test vectors
482 */
483 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
484 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
485 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
486 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
487 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
488 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
489 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
490 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
491 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
492 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
493 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
494 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
495};
496
497/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 * Checkup routine
499 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000501{
Paul Bakker5b4af392014-06-26 12:09:34 +0200502 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500503 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200504 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
Russ Butlerbb83b422016-10-12 17:36:50 -0500507 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
508 if( NULL == buf )
509 {
510 if( verbose != 0 )
511 mbedtls_printf( "Buffer allocation failed\n" );
512
513 return( 1 );
514 }
515
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200516 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200517
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 for( i = 0; i < 6; i++ )
519 {
520 j = i % 3;
521 k = i < 3;
522
523 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000525
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100526 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100527 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
529 if( j == 2 )
530 {
531 memset( buf, 'a', buflen = 1000 );
532
533 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100534 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100535 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100536 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100537 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100538 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100539
Paul Bakker5121ce52009-01-03 21:22:43 +0000540 }
541 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100542 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100543 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100544 sha256_test_buflen[j] );
545 if( ret != 0 )
546 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100547 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000548
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100549 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100550 goto fail;
551
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
Paul Bakker9e36f042013-06-30 14:34:05 +0200553 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100554 {
555 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100556 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100557 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
559 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000561 }
562
563 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100566 goto exit;
567
568fail:
569 if( verbose != 0 )
570 mbedtls_printf( "failed\n" );
571
Paul Bakker5b4af392014-06-26 12:09:34 +0200572exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500574 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200575
576 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000577}
578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581#endif /* MBEDTLS_SHA256_C */