blob: bf52eaea066bf0f69b0eec79a5b7010331babda4 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
23 *
24 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
25 */
26
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020029#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Andrzej Kurek78f77eb2020-06-04 08:09:53 -040037#include "mbedtls/platform.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_SELF_TEST)
42#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#else
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050046#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050048#define mbedtls_calloc calloc
49#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Hanno Becker2f6de422018-12-20 10:22:32 +000053#define SHA256_VALIDATE_RET(cond) \
54 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
55#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
56
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020057#if !defined(MBEDTLS_SHA256_ALT)
58
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020060{
Hanno Becker8d215e72018-12-18 17:53:21 +000061 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000062
Manuel Pégourié-Gonnard99419332019-10-03 10:40:57 +020063 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020064}
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020067{
68 if( ctx == NULL )
69 return;
70
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050071 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020072}
73
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020074void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
75 const mbedtls_sha256_context *src )
76{
Hanno Becker8d215e72018-12-18 17:53:21 +000077 SHA256_VALIDATE( dst != NULL );
78 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000079
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020080 *dst = *src;
81}
82
Paul Bakker5121ce52009-01-03 21:22:43 +000083/*
84 * SHA-256 context setup
85 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010086int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +000087{
Hanno Becker8d215e72018-12-18 17:53:21 +000088 SHA256_VALIDATE_RET( ctx != NULL );
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +020089#if defined(MBEDTLS_SHA256_NO_SHA224)
90 SHA256_VALIDATE_RET( is224 == 0 );
91 (void) is224;
92#else
Hanno Becker8d215e72018-12-18 17:53:21 +000093 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +020094#endif
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000095
Paul Bakker5121ce52009-01-03 21:22:43 +000096 ctx->total[0] = 0;
97 ctx->total[1] = 0;
98
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +020099#if !defined(MBEDTLS_SHA256_NO_SHA224)
100 ctx->is224 = is224;
101
102 if( is224 == 1 )
103 {
104 /* SHA-224 */
105 ctx->state[0] = 0xC1059ED8;
106 ctx->state[1] = 0x367CD507;
107 ctx->state[2] = 0x3070DD17;
108 ctx->state[3] = 0xF70E5939;
109 ctx->state[4] = 0xFFC00B31;
110 ctx->state[5] = 0x68581511;
111 ctx->state[6] = 0x64F98FA7;
112 ctx->state[7] = 0xBEFA4FA4;
113 }
114 else
115#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000116 {
117 /* SHA-256 */
118 ctx->state[0] = 0x6A09E667;
119 ctx->state[1] = 0xBB67AE85;
120 ctx->state[2] = 0x3C6EF372;
121 ctx->state[3] = 0xA54FF53A;
122 ctx->state[4] = 0x510E527F;
123 ctx->state[5] = 0x9B05688C;
124 ctx->state[6] = 0x1F83D9AB;
125 ctx->state[7] = 0x5BE0CD19;
126 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100127
128 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000129}
130
Jaeden Amero041039f2018-02-19 15:28:08 +0000131#if !defined(MBEDTLS_DEPRECATED_REMOVED)
132void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
133 int is224 )
134{
135 mbedtls_sha256_starts_ret( ctx, is224 );
136}
137#endif
138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200139#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200140static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000141{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200142 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
143 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
144 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
145 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
146 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
147 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
148 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
149 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
150 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
151 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
152 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
153 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
154 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
155 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
156 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
157 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
158};
Paul Bakker5121ce52009-01-03 21:22:43 +0000159
Hanno Beckerd6028a12018-10-15 12:01:35 +0100160#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
161#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
163#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
164#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
165
166#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
167#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
168
Hanno Beckerd6028a12018-10-15 12:01:35 +0100169#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
170#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000171
172#define R(t) \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100173 ( \
174 W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
175 S0(W[(t) - 15]) + W[(t) - 16] \
176 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000177
Hanno Beckerd6028a12018-10-15 12:01:35 +0100178#define P(a,b,c,d,e,f,g,h,x,K) \
179 do \
180 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100181 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
182 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100183 (d) += temp1; (h) = temp1 + temp2; \
184 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000185
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100186int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100187 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200188{
189 uint32_t temp1, temp2, W[64];
190 uint32_t A[8];
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400191 uint32_t flow_ctrl = 0;
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200192 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000193
Hanno Becker8d215e72018-12-18 17:53:21 +0000194 SHA256_VALIDATE_RET( ctx != NULL );
195 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000196
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200197 for( i = 0; i < 8; i++ )
198 A[i] = ctx->state[i];
199
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200200#if defined(MBEDTLS_SHA256_SMALLER)
Jarno Lamsabb86c522020-01-07 13:33:45 +0200201 {
202 uint32_t offset = mbedtls_platform_random_in_range(16);
203 mbedtls_platform_memset( W, 0, sizeof( W ) );
204
205 for( i = offset; i < 16; i++ )
206 {
207 W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400208 flow_ctrl++;
Jarno Lamsabb86c522020-01-07 13:33:45 +0200209 }
210 for( i = 0; i < offset; i++ )
211 {
212 W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400213 flow_ctrl++;
Jarno Lamsabb86c522020-01-07 13:33:45 +0200214 }
215 }
216
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400217 if( flow_ctrl != 16 )
218 {
219 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
220 }
221
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200222 for( i = 0; i < 64; i++ )
223 {
Jarno Lamsabb86c522020-01-07 13:33:45 +0200224 if( i >= 16 )
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200225 R( i );
226
227 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
228
229 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
230 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400231 flow_ctrl++;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200232 }
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400233
234 if( flow_ctrl != 80 )
235 {
236 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
237 }
238
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200239#else /* MBEDTLS_SHA256_SMALLER */
240 for( i = 0; i < 16; i++ )
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400241 {
Arto Kinnunen4f4849a2019-09-09 10:21:18 +0300242 W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400243 flow_ctrl++;
244 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200245
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200246 for( i = 0; i < 16; i += 8 )
247 {
248 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
249 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
250 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
251 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
252 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
253 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
254 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
255 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400256 flow_ctrl++;
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200257 }
258
259 for( i = 16; i < 64; i += 8 )
260 {
261 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
262 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
263 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
264 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
265 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
266 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
267 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
268 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400269 flow_ctrl++;
270 }
271
272 /* 16 from the first loop, 2 from the second and 6 from the third. */
273 if( flow_ctrl != 24 )
274 {
275 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200276 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200277#endif /* MBEDTLS_SHA256_SMALLER */
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400278 flow_ctrl = 0;
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200279
280 for( i = 0; i < 8; i++ )
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400281 {
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200282 ctx->state[i] += A[i];
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400283 flow_ctrl++;
284 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100285
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400286 if( flow_ctrl == 8 )
287 {
288 return( 0 );
289 }
290
291 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000292}
Jaeden Amero041039f2018-02-19 15:28:08 +0000293
294#if !defined(MBEDTLS_DEPRECATED_REMOVED)
295void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
296 const unsigned char data[64] )
297{
298 mbedtls_internal_sha256_process( ctx, data );
299}
300#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
303/*
304 * SHA-256 process buffer
305 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100306int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100307 const unsigned char *input,
308 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000309{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100310 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000311 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000312 uint32_t left;
Andrzej Kurek74f7d0f2020-07-06 14:28:12 -0400313 volatile const unsigned char *input_dup = input;
314 volatile size_t ilen_dup = ilen;
315 size_t ilen_change;
Hanno Becker8d215e72018-12-18 17:53:21 +0000316 SHA256_VALIDATE_RET( ctx != NULL );
317 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000318
Brian White12895d12014-04-11 11:29:42 -0400319 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100320 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
322 left = ctx->total[0] & 0x3F;
323 fill = 64 - left;
324
Paul Bakker5c2364c2012-10-01 14:41:15 +0000325 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 ctx->total[0] &= 0xFFFFFFFF;
327
Paul Bakker5c2364c2012-10-01 14:41:15 +0000328 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 ctx->total[1]++;
330
331 if( left && ilen >= fill )
332 {
Teppo Järvelin91d79382019-10-02 09:09:31 +0300333 mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100334
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100335 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100336 return( ret );
337
Paul Bakker5121ce52009-01-03 21:22:43 +0000338 input += fill;
339 ilen -= fill;
340 left = 0;
341 }
342
343 while( ilen >= 64 )
344 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100345 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100346 return( ret );
347
Paul Bakker5121ce52009-01-03 21:22:43 +0000348 input += 64;
349 ilen -= 64;
350 }
351
352 if( ilen > 0 )
Teppo Järvelin91d79382019-10-02 09:09:31 +0300353 mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100354
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400355 /* Re-check ilen to protect from a FI attack */
356 if( ilen < 64 )
357 {
Andrzej Kurek74f7d0f2020-07-06 14:28:12 -0400358 /* Re-check that the calculated offsets are correct */
359 ilen_change = ilen_dup - ilen;
360 if( ( input_dup + ilen_change ) == input )
361 {
362 return( 0 );
363 }
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400364 }
365 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000366}
367
Jaeden Amero041039f2018-02-19 15:28:08 +0000368#if !defined(MBEDTLS_DEPRECATED_REMOVED)
369void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
370 const unsigned char *input,
371 size_t ilen )
372{
373 mbedtls_sha256_update_ret( ctx, input, ilen );
374}
375#endif
376
Paul Bakker5121ce52009-01-03 21:22:43 +0000377/*
378 * SHA-256 final digest
379 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100380int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100381 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000382{
Arto Kinnunen9b3b1942019-09-09 17:02:35 +0300383 int ret, s_pos, o_pos;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200384 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000385 uint32_t high, low;
Jarno Lamsabb86c522020-01-07 13:33:45 +0200386 uint32_t offset = 0;
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400387 uint32_t flow_ctrl = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
Hanno Becker8d215e72018-12-18 17:53:21 +0000389 SHA256_VALIDATE_RET( ctx != NULL );
390 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000391
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200392 /*
393 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
394 */
395 used = ctx->total[0] & 0x3F;
396
397 ctx->buffer[used++] = 0x80;
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400398 flow_ctrl++;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200399
400 if( used <= 56 )
401 {
402 /* Enough room for padding + length in current block */
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200403 mbedtls_platform_memset( ctx->buffer + used, 0, 56 - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200404 }
405 else
406 {
407 /* We'll need an extra block */
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200408 mbedtls_platform_memset( ctx->buffer + used, 0, 64 - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200409
410 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
411 return( ret );
412
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200413 mbedtls_platform_memset( ctx->buffer, 0, 56 );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200414 }
415
416 /*
417 * Add message length
418 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 high = ( ctx->total[0] >> 29 )
420 | ( ctx->total[1] << 3 );
421 low = ( ctx->total[0] << 3 );
422
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300423 (void)mbedtls_platform_put_uint32_be( ctx->buffer + 56, high );
424 (void)mbedtls_platform_put_uint32_be( ctx->buffer + 60, low );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400425 flow_ctrl++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200427 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100428 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100429
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200430 /*
431 * Output final state
432 */
Jarno Lamsabb86c522020-01-07 13:33:45 +0200433 offset = mbedtls_platform_random_in_range(7);
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300434
Jarno Lamsabb86c522020-01-07 13:33:45 +0200435 mbedtls_platform_memset( output, 0, 32 );
436
437 for( s_pos = offset, o_pos = offset * 4; s_pos < 7;
438 s_pos++, o_pos += 4 )
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300439 {
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300440 (void)mbedtls_platform_put_uint32_be( &output[o_pos],
Jarno Lamsabb86c522020-01-07 13:33:45 +0200441 ctx->state[s_pos] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400442 flow_ctrl++;
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300443 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200445#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 if( ctx->is224 == 0 )
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200447#endif
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300448 (void)mbedtls_platform_put_uint32_be( &output[28], ctx->state[7] );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100449
Jarno Lamsabb86c522020-01-07 13:33:45 +0200450 for( s_pos = 0, o_pos = 0; s_pos < (int)offset; s_pos++, o_pos += 4 )
451 {
452 (void)mbedtls_platform_put_uint32_be( &output[o_pos],
453 ctx->state[s_pos] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400454 flow_ctrl++;
Jarno Lamsabb86c522020-01-07 13:33:45 +0200455 }
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400456 /* flow ctrl was incremented twice and then 7 times in two loops */
457 if( flow_ctrl == 9 )
458 {
459 return( 0 );
460 }
461 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000462}
463
Jaeden Amero041039f2018-02-19 15:28:08 +0000464#if !defined(MBEDTLS_DEPRECATED_REMOVED)
465void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
466 unsigned char output[32] )
467{
468 mbedtls_sha256_finish_ret( ctx, output );
469}
470#endif
471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200473
Paul Bakker5121ce52009-01-03 21:22:43 +0000474/*
475 * output = SHA-256( input buffer )
476 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100477int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100478 size_t ilen,
479 unsigned char output[32],
480 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000481{
Andrzej Kurek74f7d0f2020-07-06 14:28:12 -0400482 int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483 mbedtls_sha256_context ctx;
Andrzej Kurek74f7d0f2020-07-06 14:28:12 -0400484 volatile const unsigned char *input_dup = input;
485 volatile size_t ilen_dup = ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
Hanno Becker8d215e72018-12-18 17:53:21 +0000487 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
488 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
489 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100492
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100493 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100494 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100495
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100496 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100497 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100498
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100499 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100500 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100501
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100502exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100504
Andrzej Kurek74f7d0f2020-07-06 14:28:12 -0400505 if( input_dup == input && ilen_dup == ilen )
506 {
507 return( ret );
508 }
509 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000510}
511
Jaeden Amero041039f2018-02-19 15:28:08 +0000512#if !defined(MBEDTLS_DEPRECATED_REMOVED)
513void mbedtls_sha256( const unsigned char *input,
514 size_t ilen,
515 unsigned char output[32],
516 int is224 )
517{
518 mbedtls_sha256_ret( input, ilen, output, is224 );
519}
520#endif
521
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000523/*
524 * FIPS-180-2 test vectors
525 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000526static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000527{
528 { "abc" },
529 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
530 { "" }
531};
532
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100533static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000534{
535 3, 56, 1000
536};
537
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200538static const unsigned char sha256_test_sum[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000539{
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200540#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000541 /*
542 * SHA-224 test vectors
543 */
544 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
545 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
546 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
547 0xE3, 0x6C, 0x9D, 0xA7 },
548 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
549 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
550 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
551 0x52, 0x52, 0x25, 0x25 },
552 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
553 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
554 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
555 0x4E, 0xE7, 0xAD, 0x67 },
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200556#endif /* !MBEDTLS_SHA256_NO_SHA224 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
558 /*
559 * SHA-256 test vectors
560 */
561 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
562 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
563 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
564 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
565 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
566 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
567 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
568 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
569 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
570 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
571 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
572 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
573};
574
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200575#define SHA256_TEST_SUM_N \
576 ( sizeof( sha256_test_sum ) / sizeof( sha256_test_sum[0] ) )
577
Paul Bakker5121ce52009-01-03 21:22:43 +0000578/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 * Checkup routine
580 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000582{
Paul Bakker5b4af392014-06-26 12:09:34 +0200583 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500584 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200585 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
Russ Butlerbb83b422016-10-12 17:36:50 -0500588 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
589 if( NULL == buf )
590 {
591 if( verbose != 0 )
592 mbedtls_printf( "Buffer allocation failed\n" );
593
594 return( 1 );
595 }
596
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200598
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200599 for( i = 0; i < (int) SHA256_TEST_SUM_N; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000600 {
601 j = i % 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200602#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000603 k = i < 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200604#else
605 k = 0;
606#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
608 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100611 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100612 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614 if( j == 2 )
615 {
Teppo Järvelind49d2b62019-10-30 13:48:12 +0200616 memset( buf, 'a', buflen = 1000 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
618 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100619 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100620 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100621 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100622 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100623 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100624
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 }
626 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100627 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100628 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100629 sha256_test_buflen[j] );
630 if( ret != 0 )
631 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100632 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100634 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100635 goto fail;
636
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Paul Bakker9e36f042013-06-30 14:34:05 +0200638 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100639 {
640 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100641 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100642 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
644 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 }
647
648 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100651 goto exit;
652
653fail:
654 if( verbose != 0 )
655 mbedtls_printf( "failed\n" );
656
Paul Bakker5b4af392014-06-26 12:09:34 +0200657exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500659 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200660
661 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000662}
663
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666#endif /* MBEDTLS_SHA256_C */