blob: d4dd4859a6b55f31886d76a6a5863c6767add1a9 [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
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000047 */
48/*
49 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
50 *
51 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
52 */
53
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020056#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020058#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000061
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000062#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050063#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000064
Rich Evans00ab4702015-02-06 13:43:58 +000065#include <string.h>
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if defined(MBEDTLS_SELF_TEST)
68#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000069#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010070#else
Rich Evans00ab4702015-02-06 13:43:58 +000071#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050072#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050074#define mbedtls_calloc calloc
75#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#endif /* MBEDTLS_PLATFORM_C */
77#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010078
Hanno Becker2f6de422018-12-20 10:22:32 +000079#define SHA256_VALIDATE_RET(cond) \
80 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
81#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
82
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020083#if !defined(MBEDTLS_SHA256_ALT)
84
Paul Bakker5121ce52009-01-03 21:22:43 +000085/*
86 * 32-bit integer manipulation macros (big endian)
87 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000088#ifndef GET_UINT32_BE
89#define GET_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020090do { \
Paul Bakker5c2364c2012-10-01 14:41:15 +000091 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
92 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
93 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
94 | ( (uint32_t) (b)[(i) + 3] ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020095} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000096#endif
97
Paul Bakker5c2364c2012-10-01 14:41:15 +000098#ifndef PUT_UINT32_BE
99#define PUT_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200100do { \
Paul Bakker5121ce52009-01-03 21:22:43 +0000101 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
102 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
103 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
104 (b)[(i) + 3] = (unsigned char) ( (n) ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200105} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000106#endif
107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200109{
Hanno Becker8d215e72018-12-18 17:53:21 +0000110 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200113}
114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200116{
117 if( ctx == NULL )
118 return;
119
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500120 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200121}
122
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200123void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
124 const mbedtls_sha256_context *src )
125{
Hanno Becker8d215e72018-12-18 17:53:21 +0000126 SHA256_VALIDATE( dst != NULL );
127 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000128
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200129 *dst = *src;
130}
131
Paul Bakker5121ce52009-01-03 21:22:43 +0000132/*
133 * SHA-256 context setup
134 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100135int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000136{
Hanno Becker8d215e72018-12-18 17:53:21 +0000137 SHA256_VALIDATE_RET( ctx != NULL );
138 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000139
Paul Bakker5121ce52009-01-03 21:22:43 +0000140 ctx->total[0] = 0;
141 ctx->total[1] = 0;
142
143 if( is224 == 0 )
144 {
145 /* SHA-256 */
146 ctx->state[0] = 0x6A09E667;
147 ctx->state[1] = 0xBB67AE85;
148 ctx->state[2] = 0x3C6EF372;
149 ctx->state[3] = 0xA54FF53A;
150 ctx->state[4] = 0x510E527F;
151 ctx->state[5] = 0x9B05688C;
152 ctx->state[6] = 0x1F83D9AB;
153 ctx->state[7] = 0x5BE0CD19;
154 }
155 else
156 {
157 /* SHA-224 */
158 ctx->state[0] = 0xC1059ED8;
159 ctx->state[1] = 0x367CD507;
160 ctx->state[2] = 0x3070DD17;
161 ctx->state[3] = 0xF70E5939;
162 ctx->state[4] = 0xFFC00B31;
163 ctx->state[5] = 0x68581511;
164 ctx->state[6] = 0x64F98FA7;
165 ctx->state[7] = 0xBEFA4FA4;
166 }
167
168 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100169
170 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000171}
172
Jaeden Amero041039f2018-02-19 15:28:08 +0000173#if !defined(MBEDTLS_DEPRECATED_REMOVED)
174void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
175 int is224 )
176{
177 mbedtls_sha256_starts_ret( ctx, is224 );
178}
179#endif
180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200182static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000183{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200184 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
185 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
186 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
187 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
188 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
189 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
190 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
191 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
192 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
193 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
194 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
195 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
196 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
197 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
198 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
199 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
200};
Paul Bakker5121ce52009-01-03 21:22:43 +0000201
Hanno Beckerd6028a12018-10-15 12:01:35 +0100202#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
203#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000204
205#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
206#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
207
208#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
209#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
210
Hanno Beckerd6028a12018-10-15 12:01:35 +0100211#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
212#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000213
214#define R(t) \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100215 ( \
216 W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
217 S0(W[(t) - 15]) + W[(t) - 16] \
218 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
Hanno Beckerd6028a12018-10-15 12:01:35 +0100220#define P(a,b,c,d,e,f,g,h,x,K) \
221 do \
222 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100223 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
224 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100225 (d) += temp1; (h) = temp1 + temp2; \
226 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000227
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100228int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100229 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200230{
231 uint32_t temp1, temp2, W[64];
232 uint32_t A[8];
233 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000234
Hanno Becker8d215e72018-12-18 17:53:21 +0000235 SHA256_VALIDATE_RET( ctx != NULL );
236 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000237
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200238 for( i = 0; i < 8; i++ )
239 A[i] = ctx->state[i];
240
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200241#if defined(MBEDTLS_SHA256_SMALLER)
242 for( i = 0; i < 64; i++ )
243 {
244 if( i < 16 )
245 GET_UINT32_BE( W[i], data, 4 * i );
246 else
247 R( i );
248
249 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
250
251 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
252 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
253 }
254#else /* MBEDTLS_SHA256_SMALLER */
255 for( i = 0; i < 16; i++ )
256 GET_UINT32_BE( W[i], data, 4 * i );
257
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200258 for( i = 0; i < 16; i += 8 )
259 {
260 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
261 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
262 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
263 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
264 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
265 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
266 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
267 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
268 }
269
270 for( i = 16; i < 64; i += 8 )
271 {
272 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
273 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
274 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
275 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
276 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
277 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
278 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
279 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
280 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200281#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200282
283 for( i = 0; i < 8; i++ )
284 ctx->state[i] += A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100285
286 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000287}
Jaeden Amero041039f2018-02-19 15:28:08 +0000288
289#if !defined(MBEDTLS_DEPRECATED_REMOVED)
290void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
291 const unsigned char data[64] )
292{
293 mbedtls_internal_sha256_process( ctx, data );
294}
295#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200296#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
298/*
299 * SHA-256 process buffer
300 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100301int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100302 const unsigned char *input,
303 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000304{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100305 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000306 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
Hanno Becker8d215e72018-12-18 17:53:21 +0000309 SHA256_VALIDATE_RET( ctx != NULL );
310 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000311
Brian White12895d12014-04-11 11:29:42 -0400312 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100313 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000314
315 left = ctx->total[0] & 0x3F;
316 fill = 64 - left;
317
Paul Bakker5c2364c2012-10-01 14:41:15 +0000318 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 ctx->total[0] &= 0xFFFFFFFF;
320
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000322 ctx->total[1]++;
323
324 if( left && ilen >= fill )
325 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200326 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100327
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100328 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100329 return( ret );
330
Paul Bakker5121ce52009-01-03 21:22:43 +0000331 input += fill;
332 ilen -= fill;
333 left = 0;
334 }
335
336 while( ilen >= 64 )
337 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100338 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100339 return( ret );
340
Paul Bakker5121ce52009-01-03 21:22:43 +0000341 input += 64;
342 ilen -= 64;
343 }
344
345 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200346 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100347
348 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000349}
350
Jaeden Amero041039f2018-02-19 15:28:08 +0000351#if !defined(MBEDTLS_DEPRECATED_REMOVED)
352void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
353 const unsigned char *input,
354 size_t ilen )
355{
356 mbedtls_sha256_update_ret( ctx, input, ilen );
357}
358#endif
359
Paul Bakker5121ce52009-01-03 21:22:43 +0000360/*
361 * SHA-256 final digest
362 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100363int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100364 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000365{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100366 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200367 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000368 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000369
Hanno Becker8d215e72018-12-18 17:53:21 +0000370 SHA256_VALIDATE_RET( ctx != NULL );
371 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000372
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200373 /*
374 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
375 */
376 used = ctx->total[0] & 0x3F;
377
378 ctx->buffer[used++] = 0x80;
379
380 if( used <= 56 )
381 {
382 /* Enough room for padding + length in current block */
383 memset( ctx->buffer + used, 0, 56 - used );
384 }
385 else
386 {
387 /* We'll need an extra block */
388 memset( ctx->buffer + used, 0, 64 - used );
389
390 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
391 return( ret );
392
393 memset( ctx->buffer, 0, 56 );
394 }
395
396 /*
397 * Add message length
398 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 high = ( ctx->total[0] >> 29 )
400 | ( ctx->total[1] << 3 );
401 low = ( ctx->total[0] << 3 );
402
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200403 PUT_UINT32_BE( high, ctx->buffer, 56 );
404 PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200406 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100407 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100408
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200409 /*
410 * Output final state
411 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000412 PUT_UINT32_BE( ctx->state[0], output, 0 );
413 PUT_UINT32_BE( ctx->state[1], output, 4 );
414 PUT_UINT32_BE( ctx->state[2], output, 8 );
415 PUT_UINT32_BE( ctx->state[3], output, 12 );
416 PUT_UINT32_BE( ctx->state[4], output, 16 );
417 PUT_UINT32_BE( ctx->state[5], output, 20 );
418 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420 if( ctx->is224 == 0 )
Paul Bakker5c2364c2012-10-01 14:41:15 +0000421 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100422
423 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424}
425
Jaeden Amero041039f2018-02-19 15:28:08 +0000426#if !defined(MBEDTLS_DEPRECATED_REMOVED)
427void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
428 unsigned char output[32] )
429{
430 mbedtls_sha256_finish_ret( ctx, output );
431}
432#endif
433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200435
Paul Bakker5121ce52009-01-03 21:22:43 +0000436/*
437 * output = SHA-256( input buffer )
438 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100439int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100440 size_t ilen,
441 unsigned char output[32],
442 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000443{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100444 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
Hanno Becker8d215e72018-12-18 17:53:21 +0000447 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
448 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
449 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000450
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100452
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100453 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100454 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100455
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100456 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100457 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100458
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100459 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100460 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100461
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100462exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100464
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100465 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000466}
467
Jaeden Amero041039f2018-02-19 15:28:08 +0000468#if !defined(MBEDTLS_DEPRECATED_REMOVED)
469void mbedtls_sha256( const unsigned char *input,
470 size_t ilen,
471 unsigned char output[32],
472 int is224 )
473{
474 mbedtls_sha256_ret( input, ilen, output, is224 );
475}
476#endif
477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000479/*
480 * FIPS-180-2 test vectors
481 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000482static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000483{
484 { "abc" },
485 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
486 { "" }
487};
488
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100489static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000490{
491 3, 56, 1000
492};
493
Paul Bakker9e36f042013-06-30 14:34:05 +0200494static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000495{
496 /*
497 * SHA-224 test vectors
498 */
499 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
500 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
501 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
502 0xE3, 0x6C, 0x9D, 0xA7 },
503 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
504 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
505 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
506 0x52, 0x52, 0x25, 0x25 },
507 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
508 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
509 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
510 0x4E, 0xE7, 0xAD, 0x67 },
511
512 /*
513 * SHA-256 test vectors
514 */
515 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
516 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
517 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
518 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
519 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
520 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
521 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
522 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
523 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
524 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
525 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
526 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
527};
528
529/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000530 * Checkup routine
531 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000533{
Paul Bakker5b4af392014-06-26 12:09:34 +0200534 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500535 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200536 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000538
Russ Butlerbb83b422016-10-12 17:36:50 -0500539 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
540 if( NULL == buf )
541 {
542 if( verbose != 0 )
543 mbedtls_printf( "Buffer allocation failed\n" );
544
545 return( 1 );
546 }
547
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200548 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200549
Paul Bakker5121ce52009-01-03 21:22:43 +0000550 for( i = 0; i < 6; i++ )
551 {
552 j = i % 3;
553 k = i < 3;
554
555 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100558 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100559 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 if( j == 2 )
562 {
563 memset( buf, 'a', buflen = 1000 );
564
565 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100566 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100567 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100568 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100569 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100570 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100571
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 }
573 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100574 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100575 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100576 sha256_test_buflen[j] );
577 if( ret != 0 )
578 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100579 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100581 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100582 goto fail;
583
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
Paul Bakker9e36f042013-06-30 14:34:05 +0200585 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100586 {
587 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100588 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100589 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000590
591 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 }
594
595 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100598 goto exit;
599
600fail:
601 if( verbose != 0 )
602 mbedtls_printf( "failed\n" );
603
Paul Bakker5b4af392014-06-26 12:09:34 +0200604exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500606 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200607
608 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609}
610
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613#endif /* MBEDTLS_SHA256_C */