blob: 07b899d0787f3e6f6e836af06b5beafb050f8c37 [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;
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
Hanno Becker8d215e72018-12-18 17:53:21 +0000314 SHA256_VALIDATE_RET( ctx != NULL );
315 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000316
Brian White12895d12014-04-11 11:29:42 -0400317 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100318 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
320 left = ctx->total[0] & 0x3F;
321 fill = 64 - left;
322
Paul Bakker5c2364c2012-10-01 14:41:15 +0000323 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000324 ctx->total[0] &= 0xFFFFFFFF;
325
Paul Bakker5c2364c2012-10-01 14:41:15 +0000326 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000327 ctx->total[1]++;
328
329 if( left && ilen >= fill )
330 {
Teppo Järvelin91d79382019-10-02 09:09:31 +0300331 mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100332
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100333 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100334 return( ret );
335
Paul Bakker5121ce52009-01-03 21:22:43 +0000336 input += fill;
337 ilen -= fill;
338 left = 0;
339 }
340
341 while( ilen >= 64 )
342 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100343 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100344 return( ret );
345
Paul Bakker5121ce52009-01-03 21:22:43 +0000346 input += 64;
347 ilen -= 64;
348 }
349
350 if( ilen > 0 )
Teppo Järvelin91d79382019-10-02 09:09:31 +0300351 mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100352
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400353 /* Re-check ilen to protect from a FI attack */
354 if( ilen < 64 )
355 {
356 return( 0 );
357 }
358 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000359}
360
Jaeden Amero041039f2018-02-19 15:28:08 +0000361#if !defined(MBEDTLS_DEPRECATED_REMOVED)
362void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
363 const unsigned char *input,
364 size_t ilen )
365{
366 mbedtls_sha256_update_ret( ctx, input, ilen );
367}
368#endif
369
Paul Bakker5121ce52009-01-03 21:22:43 +0000370/*
371 * SHA-256 final digest
372 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100373int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100374 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000375{
Arto Kinnunen9b3b1942019-09-09 17:02:35 +0300376 int ret, s_pos, o_pos;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200377 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000378 uint32_t high, low;
Jarno Lamsabb86c522020-01-07 13:33:45 +0200379 uint32_t offset = 0;
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400380 uint32_t flow_ctrl = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
Hanno Becker8d215e72018-12-18 17:53:21 +0000382 SHA256_VALIDATE_RET( ctx != NULL );
383 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000384
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200385 /*
386 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
387 */
388 used = ctx->total[0] & 0x3F;
389
390 ctx->buffer[used++] = 0x80;
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400391 flow_ctrl++;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200392
393 if( used <= 56 )
394 {
395 /* Enough room for padding + length in current block */
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200396 mbedtls_platform_memset( ctx->buffer + used, 0, 56 - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200397 }
398 else
399 {
400 /* We'll need an extra block */
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200401 mbedtls_platform_memset( ctx->buffer + used, 0, 64 - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200402
403 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
404 return( ret );
405
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200406 mbedtls_platform_memset( ctx->buffer, 0, 56 );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200407 }
408
409 /*
410 * Add message length
411 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 high = ( ctx->total[0] >> 29 )
413 | ( ctx->total[1] << 3 );
414 low = ( ctx->total[0] << 3 );
415
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300416 (void)mbedtls_platform_put_uint32_be( ctx->buffer + 56, high );
417 (void)mbedtls_platform_put_uint32_be( ctx->buffer + 60, low );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400418 flow_ctrl++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200420 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100421 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100422
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200423 /*
424 * Output final state
425 */
Jarno Lamsabb86c522020-01-07 13:33:45 +0200426 offset = mbedtls_platform_random_in_range(7);
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300427
Jarno Lamsabb86c522020-01-07 13:33:45 +0200428 mbedtls_platform_memset( output, 0, 32 );
429
430 for( s_pos = offset, o_pos = offset * 4; s_pos < 7;
431 s_pos++, o_pos += 4 )
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300432 {
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300433 (void)mbedtls_platform_put_uint32_be( &output[o_pos],
Jarno Lamsabb86c522020-01-07 13:33:45 +0200434 ctx->state[s_pos] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400435 flow_ctrl++;
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300436 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200438#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 if( ctx->is224 == 0 )
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200440#endif
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300441 (void)mbedtls_platform_put_uint32_be( &output[28], ctx->state[7] );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100442
Jarno Lamsabb86c522020-01-07 13:33:45 +0200443 for( s_pos = 0, o_pos = 0; s_pos < (int)offset; s_pos++, o_pos += 4 )
444 {
445 (void)mbedtls_platform_put_uint32_be( &output[o_pos],
446 ctx->state[s_pos] );
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400447 flow_ctrl++;
Jarno Lamsabb86c522020-01-07 13:33:45 +0200448 }
Andrzej Kurek78f77eb2020-06-04 08:09:53 -0400449 /* flow ctrl was incremented twice and then 7 times in two loops */
450 if( flow_ctrl == 9 )
451 {
452 return( 0 );
453 }
454 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455}
456
Jaeden Amero041039f2018-02-19 15:28:08 +0000457#if !defined(MBEDTLS_DEPRECATED_REMOVED)
458void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
459 unsigned char output[32] )
460{
461 mbedtls_sha256_finish_ret( ctx, output );
462}
463#endif
464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200466
Paul Bakker5121ce52009-01-03 21:22:43 +0000467/*
468 * output = SHA-256( input buffer )
469 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100470int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100471 size_t ilen,
472 unsigned char output[32],
473 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000474{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100475 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Hanno Becker8d215e72018-12-18 17:53:21 +0000478 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
479 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
480 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100483
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100484 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100485 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100486
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100487 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100488 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100489
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100490 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100491 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100492
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100493exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100495
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100496 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000497}
498
Jaeden Amero041039f2018-02-19 15:28:08 +0000499#if !defined(MBEDTLS_DEPRECATED_REMOVED)
500void mbedtls_sha256( const unsigned char *input,
501 size_t ilen,
502 unsigned char output[32],
503 int is224 )
504{
505 mbedtls_sha256_ret( input, ilen, output, is224 );
506}
507#endif
508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000510/*
511 * FIPS-180-2 test vectors
512 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000513static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000514{
515 { "abc" },
516 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
517 { "" }
518};
519
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100520static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000521{
522 3, 56, 1000
523};
524
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200525static const unsigned char sha256_test_sum[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000526{
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200527#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 /*
529 * SHA-224 test vectors
530 */
531 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
532 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
533 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
534 0xE3, 0x6C, 0x9D, 0xA7 },
535 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
536 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
537 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
538 0x52, 0x52, 0x25, 0x25 },
539 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
540 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
541 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
542 0x4E, 0xE7, 0xAD, 0x67 },
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200543#endif /* !MBEDTLS_SHA256_NO_SHA224 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000544
545 /*
546 * SHA-256 test vectors
547 */
548 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
549 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
550 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
551 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
552 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
553 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
554 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
555 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
556 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
557 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
558 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
559 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
560};
561
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200562#define SHA256_TEST_SUM_N \
563 ( sizeof( sha256_test_sum ) / sizeof( sha256_test_sum[0] ) )
564
Paul Bakker5121ce52009-01-03 21:22:43 +0000565/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000566 * Checkup routine
567 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000569{
Paul Bakker5b4af392014-06-26 12:09:34 +0200570 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500571 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200572 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
Russ Butlerbb83b422016-10-12 17:36:50 -0500575 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
576 if( NULL == buf )
577 {
578 if( verbose != 0 )
579 mbedtls_printf( "Buffer allocation failed\n" );
580
581 return( 1 );
582 }
583
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200585
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200586 for( i = 0; i < (int) SHA256_TEST_SUM_N; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 {
588 j = i % 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200589#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000590 k = i < 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200591#else
592 k = 0;
593#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000594
595 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100598 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100599 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
601 if( j == 2 )
602 {
Teppo Järvelind49d2b62019-10-30 13:48:12 +0200603 memset( buf, 'a', buflen = 1000 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100606 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100607 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100608 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100609 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100610 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100611
Paul Bakker5121ce52009-01-03 21:22:43 +0000612 }
613 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100614 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100615 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100616 sha256_test_buflen[j] );
617 if( ret != 0 )
618 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100619 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100621 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100622 goto fail;
623
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
Paul Bakker9e36f042013-06-30 14:34:05 +0200625 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100626 {
627 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100628 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100629 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
631 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 }
634
635 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100638 goto exit;
639
640fail:
641 if( verbose != 0 )
642 mbedtls_printf( "failed\n" );
643
Paul Bakker5b4af392014-06-26 12:09:34 +0200644exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500646 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200647
648 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649}
650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653#endif /* MBEDTLS_SHA256_C */