blob: be373d9cb0b0efe72faa5fa1201b4306a18080e3 [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
Paul Bakker5121ce52009-01-03 21:22:43 +0000108 ctx->total[0] = 0;
109 ctx->total[1] = 0;
110
111 if( is224 == 0 )
112 {
113 /* SHA-256 */
114 ctx->state[0] = 0x6A09E667;
115 ctx->state[1] = 0xBB67AE85;
116 ctx->state[2] = 0x3C6EF372;
117 ctx->state[3] = 0xA54FF53A;
118 ctx->state[4] = 0x510E527F;
119 ctx->state[5] = 0x9B05688C;
120 ctx->state[6] = 0x1F83D9AB;
121 ctx->state[7] = 0x5BE0CD19;
122 }
123 else
124 {
125 /* SHA-224 */
126 ctx->state[0] = 0xC1059ED8;
127 ctx->state[1] = 0x367CD507;
128 ctx->state[2] = 0x3070DD17;
129 ctx->state[3] = 0xF70E5939;
130 ctx->state[4] = 0xFFC00B31;
131 ctx->state[5] = 0x68581511;
132 ctx->state[6] = 0x64F98FA7;
133 ctx->state[7] = 0xBEFA4FA4;
134 }
135
136 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100137
138 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000139}
140
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200141#if !defined(MBEDTLS_DEPRECATED_REMOVED)
142void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
143 int is224 )
144{
145 mbedtls_sha256_starts_ret( ctx, is224 );
146}
147#endif
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é-Gonnard93c08472021-04-15 12:23:55 +0200284#if !defined(MBEDTLS_DEPRECATED_REMOVED)
285void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
286 const unsigned char data[64] )
287{
288 mbedtls_internal_sha256_process( ctx, data );
289}
290#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000292
293/*
294 * SHA-256 process buffer
295 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100296int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100297 const unsigned char *input,
298 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000299{
Janos Follath24eed8d2019-11-22 13:21:35 +0000300 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000301 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000302 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
Hanno Becker8d215e72018-12-18 17:53:21 +0000304 SHA256_VALIDATE_RET( ctx != NULL );
305 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000306
Brian White12895d12014-04-11 11:29:42 -0400307 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100308 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000309
310 left = ctx->total[0] & 0x3F;
311 fill = 64 - left;
312
Paul Bakker5c2364c2012-10-01 14:41:15 +0000313 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000314 ctx->total[0] &= 0xFFFFFFFF;
315
Paul Bakker5c2364c2012-10-01 14:41:15 +0000316 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000317 ctx->total[1]++;
318
319 if( left && ilen >= fill )
320 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200321 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100322
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100323 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100324 return( ret );
325
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 input += fill;
327 ilen -= fill;
328 left = 0;
329 }
330
331 while( ilen >= 64 )
332 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100333 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100334 return( ret );
335
Paul Bakker5121ce52009-01-03 21:22:43 +0000336 input += 64;
337 ilen -= 64;
338 }
339
340 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200341 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100342
343 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000344}
345
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200346#if !defined(MBEDTLS_DEPRECATED_REMOVED)
347void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
348 const unsigned char *input,
349 size_t ilen )
350{
351 mbedtls_sha256_update_ret( ctx, input, ilen );
352}
353#endif
354
Paul Bakker5121ce52009-01-03 21:22:43 +0000355/*
356 * SHA-256 final digest
357 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100358int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100359 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000360{
Janos Follath24eed8d2019-11-22 13:21:35 +0000361 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200362 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000363 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
Hanno Becker8d215e72018-12-18 17:53:21 +0000365 SHA256_VALIDATE_RET( ctx != NULL );
366 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000367
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200368 /*
369 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
370 */
371 used = ctx->total[0] & 0x3F;
372
373 ctx->buffer[used++] = 0x80;
374
375 if( used <= 56 )
376 {
377 /* Enough room for padding + length in current block */
378 memset( ctx->buffer + used, 0, 56 - used );
379 }
380 else
381 {
382 /* We'll need an extra block */
383 memset( ctx->buffer + used, 0, 64 - used );
384
385 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
386 return( ret );
387
388 memset( ctx->buffer, 0, 56 );
389 }
390
391 /*
392 * Add message length
393 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 high = ( ctx->total[0] >> 29 )
395 | ( ctx->total[1] << 3 );
396 low = ( ctx->total[0] << 3 );
397
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200398 PUT_UINT32_BE( high, ctx->buffer, 56 );
399 PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200401 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100402 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100403
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200404 /*
405 * Output final state
406 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000407 PUT_UINT32_BE( ctx->state[0], output, 0 );
408 PUT_UINT32_BE( ctx->state[1], output, 4 );
409 PUT_UINT32_BE( ctx->state[2], output, 8 );
410 PUT_UINT32_BE( ctx->state[3], output, 12 );
411 PUT_UINT32_BE( ctx->state[4], output, 16 );
412 PUT_UINT32_BE( ctx->state[5], output, 20 );
413 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
415 if( ctx->is224 == 0 )
Paul Bakker5c2364c2012-10-01 14:41:15 +0000416 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100417
418 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419}
420
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200421#if !defined(MBEDTLS_DEPRECATED_REMOVED)
422void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
423 unsigned char output[32] )
424{
425 mbedtls_sha256_finish_ret( ctx, output );
426}
427#endif
428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200430
Paul Bakker5121ce52009-01-03 21:22:43 +0000431/*
432 * output = SHA-256( input buffer )
433 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100434int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100435 size_t ilen,
436 unsigned char output[32],
437 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000438{
Janos Follath24eed8d2019-11-22 13:21:35 +0000439 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
Hanno Becker8d215e72018-12-18 17:53:21 +0000442 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
443 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
444 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100447
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100448 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100449 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100450
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100451 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100452 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100453
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100454 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100455 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100456
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100457exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100459
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100460 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000461}
462
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200463#if !defined(MBEDTLS_DEPRECATED_REMOVED)
464void mbedtls_sha256( const unsigned char *input,
465 size_t ilen,
466 unsigned char output[32],
467 int is224 )
468{
469 mbedtls_sha256_ret( input, ilen, output, is224 );
470}
471#endif
472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000474/*
475 * FIPS-180-2 test vectors
476 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000477static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000478{
479 { "abc" },
480 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
481 { "" }
482};
483
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100484static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000485{
486 3, 56, 1000
487};
488
Paul Bakker9e36f042013-06-30 14:34:05 +0200489static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000490{
491 /*
492 * SHA-224 test vectors
493 */
494 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
495 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
496 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
497 0xE3, 0x6C, 0x9D, 0xA7 },
498 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
499 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
500 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
501 0x52, 0x52, 0x25, 0x25 },
502 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
503 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
504 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
505 0x4E, 0xE7, 0xAD, 0x67 },
506
507 /*
508 * SHA-256 test vectors
509 */
510 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
511 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
512 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
513 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
514 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
515 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
516 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
517 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
518 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
519 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
520 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
521 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
522};
523
524/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000525 * Checkup routine
526 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000528{
Paul Bakker5b4af392014-06-26 12:09:34 +0200529 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500530 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200531 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Russ Butlerbb83b422016-10-12 17:36:50 -0500534 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
535 if( NULL == buf )
536 {
537 if( verbose != 0 )
538 mbedtls_printf( "Buffer allocation failed\n" );
539
540 return( 1 );
541 }
542
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200544
Paul Bakker5121ce52009-01-03 21:22:43 +0000545 for( i = 0; i < 6; i++ )
546 {
547 j = i % 3;
548 k = i < 3;
549
550 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100553 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100554 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 if( j == 2 )
557 {
558 memset( buf, 'a', buflen = 1000 );
559
560 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100561 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100562 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100563 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100564 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100565 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100566
Paul Bakker5121ce52009-01-03 21:22:43 +0000567 }
568 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100569 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100570 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100571 sha256_test_buflen[j] );
572 if( ret != 0 )
573 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100574 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100576 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100577 goto fail;
578
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Paul Bakker9e36f042013-06-30 14:34:05 +0200580 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100581 {
582 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100583 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100584 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
586 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000588 }
589
590 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000592
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100593 goto exit;
594
595fail:
596 if( verbose != 0 )
597 mbedtls_printf( "failed\n" );
598
Paul Bakker5b4af392014-06-26 12:09:34 +0200599exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500601 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200602
603 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000604}
605
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608#endif /* MBEDTLS_SHA256_C */