blob: d8ddda5be01c6d72206b61a6d63ba8dd8ed7b046 [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
Gilles Peskinedb09ef62020-06-03 01:43:33 +020027#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000030
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050032#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000033#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Rich Evans00ab4702015-02-06 13:43:58 +000035#include <string.h>
36
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020037#if defined(MBEDTLS_SELF_TEST)
38#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000039#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010040#else
Rich Evans00ab4702015-02-06 13:43:58 +000041#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050042#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050044#define mbedtls_calloc calloc
45#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#endif /* MBEDTLS_PLATFORM_C */
47#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Hanno Becker2f6de422018-12-20 10:22:32 +000049#define SHA256_VALIDATE_RET(cond) \
50 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
51#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
52
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020053#if !defined(MBEDTLS_SHA256_ALT)
54
Paul Bakker5121ce52009-01-03 21:22:43 +000055/*
56 * 32-bit integer manipulation macros (big endian)
57 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000058#ifndef GET_UINT32_BE
59#define GET_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020060do { \
Paul Bakker5c2364c2012-10-01 14:41:15 +000061 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
62 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
63 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
64 | ( (uint32_t) (b)[(i) + 3] ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020065} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000066#endif
67
Paul Bakker5c2364c2012-10-01 14:41:15 +000068#ifndef PUT_UINT32_BE
69#define PUT_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020070do { \
Paul Bakker5121ce52009-01-03 21:22:43 +000071 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
72 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
73 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
74 (b)[(i) + 3] = (unsigned char) ( (n) ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020075} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000076#endif
77
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020079{
Hanno Becker8d215e72018-12-18 17:53:21 +000080 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000081
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020083}
84
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020085void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020086{
87 if( ctx == NULL )
88 return;
89
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050090 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020091}
92
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020093void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
94 const mbedtls_sha256_context *src )
95{
Hanno Becker8d215e72018-12-18 17:53:21 +000096 SHA256_VALIDATE( dst != NULL );
97 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000098
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020099 *dst = *src;
100}
101
Paul Bakker5121ce52009-01-03 21:22:43 +0000102/*
103 * SHA-256 context setup
104 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100105int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000106{
Hanno Becker8d215e72018-12-18 17:53:21 +0000107 SHA256_VALIDATE_RET( ctx != NULL );
108 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000109
Paul Bakker5121ce52009-01-03 21:22:43 +0000110 ctx->total[0] = 0;
111 ctx->total[1] = 0;
112
113 if( is224 == 0 )
114 {
115 /* SHA-256 */
116 ctx->state[0] = 0x6A09E667;
117 ctx->state[1] = 0xBB67AE85;
118 ctx->state[2] = 0x3C6EF372;
119 ctx->state[3] = 0xA54FF53A;
120 ctx->state[4] = 0x510E527F;
121 ctx->state[5] = 0x9B05688C;
122 ctx->state[6] = 0x1F83D9AB;
123 ctx->state[7] = 0x5BE0CD19;
124 }
125 else
126 {
127 /* SHA-224 */
128 ctx->state[0] = 0xC1059ED8;
129 ctx->state[1] = 0x367CD507;
130 ctx->state[2] = 0x3070DD17;
131 ctx->state[3] = 0xF70E5939;
132 ctx->state[4] = 0xFFC00B31;
133 ctx->state[5] = 0x68581511;
134 ctx->state[6] = 0x64F98FA7;
135 ctx->state[7] = 0xBEFA4FA4;
136 }
137
138 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100139
140 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000141}
142
Jaeden Amero041039f2018-02-19 15:28:08 +0000143#if !defined(MBEDTLS_DEPRECATED_REMOVED)
144void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
145 int is224 )
146{
147 mbedtls_sha256_starts_ret( ctx, is224 );
148}
149#endif
150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200152static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000153{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200154 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
155 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
156 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
157 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
158 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
159 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
160 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
161 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
162 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
163 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
164 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
165 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
166 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
167 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
168 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
169 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
170};
Paul Bakker5121ce52009-01-03 21:22:43 +0000171
Hanno Becker1eeca412018-10-15 12:01:35 +0100172#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
173#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000174
175#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
176#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
177
178#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
179#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
180
Hanno Becker1eeca412018-10-15 12:01:35 +0100181#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
182#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000183
184#define R(t) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100185 ( \
186 W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
187 S0(W[(t) - 15]) + W[(t) - 16] \
188 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000189
Hanno Becker1eeca412018-10-15 12:01:35 +0100190#define P(a,b,c,d,e,f,g,h,x,K) \
191 do \
192 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100193 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
194 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100195 (d) += temp1; (h) = temp1 + temp2; \
196 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100198int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100199 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200200{
201 uint32_t temp1, temp2, W[64];
202 uint32_t A[8];
203 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000204
Hanno Becker8d215e72018-12-18 17:53:21 +0000205 SHA256_VALIDATE_RET( ctx != NULL );
206 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000207
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200208 for( i = 0; i < 8; i++ )
209 A[i] = ctx->state[i];
210
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200211#if defined(MBEDTLS_SHA256_SMALLER)
212 for( i = 0; i < 64; i++ )
213 {
214 if( i < 16 )
215 GET_UINT32_BE( W[i], data, 4 * i );
216 else
217 R( i );
218
219 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
220
221 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
222 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
223 }
224#else /* MBEDTLS_SHA256_SMALLER */
225 for( i = 0; i < 16; i++ )
226 GET_UINT32_BE( W[i], data, 4 * i );
227
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200228 for( i = 0; i < 16; i += 8 )
229 {
230 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
231 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
232 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
233 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
234 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
235 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
236 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
237 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
238 }
239
240 for( i = 16; i < 64; i += 8 )
241 {
242 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
243 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
244 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
245 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
246 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
247 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
248 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
249 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
250 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200251#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200252
253 for( i = 0; i < 8; i++ )
254 ctx->state[i] += A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100255
256 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257}
Jaeden Amero041039f2018-02-19 15:28:08 +0000258
259#if !defined(MBEDTLS_DEPRECATED_REMOVED)
260void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
261 const unsigned char data[64] )
262{
263 mbedtls_internal_sha256_process( ctx, data );
264}
265#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000267
268/*
269 * SHA-256 process buffer
270 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100271int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100272 const unsigned char *input,
273 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000274{
Janos Follath24eed8d2019-11-22 13:21:35 +0000275 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000276 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000277 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000278
Hanno Becker8d215e72018-12-18 17:53:21 +0000279 SHA256_VALIDATE_RET( ctx != NULL );
280 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000281
Brian White12895d12014-04-11 11:29:42 -0400282 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100283 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000284
285 left = ctx->total[0] & 0x3F;
286 fill = 64 - left;
287
Paul Bakker5c2364c2012-10-01 14:41:15 +0000288 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 ctx->total[0] &= 0xFFFFFFFF;
290
Paul Bakker5c2364c2012-10-01 14:41:15 +0000291 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 ctx->total[1]++;
293
294 if( left && ilen >= fill )
295 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200296 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100297
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100298 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100299 return( ret );
300
Paul Bakker5121ce52009-01-03 21:22:43 +0000301 input += fill;
302 ilen -= fill;
303 left = 0;
304 }
305
306 while( ilen >= 64 )
307 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100308 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100309 return( ret );
310
Paul Bakker5121ce52009-01-03 21:22:43 +0000311 input += 64;
312 ilen -= 64;
313 }
314
315 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200316 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100317
318 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000319}
320
Jaeden Amero041039f2018-02-19 15:28:08 +0000321#if !defined(MBEDTLS_DEPRECATED_REMOVED)
322void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
323 const unsigned char *input,
324 size_t ilen )
325{
326 mbedtls_sha256_update_ret( ctx, input, ilen );
327}
328#endif
329
Paul Bakker5121ce52009-01-03 21:22:43 +0000330/*
331 * SHA-256 final digest
332 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100333int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100334 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000335{
Janos Follath24eed8d2019-11-22 13:21:35 +0000336 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200337 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000338 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
Hanno Becker8d215e72018-12-18 17:53:21 +0000340 SHA256_VALIDATE_RET( ctx != NULL );
341 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000342
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200343 /*
344 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
345 */
346 used = ctx->total[0] & 0x3F;
347
348 ctx->buffer[used++] = 0x80;
349
350 if( used <= 56 )
351 {
352 /* Enough room for padding + length in current block */
353 memset( ctx->buffer + used, 0, 56 - used );
354 }
355 else
356 {
357 /* We'll need an extra block */
358 memset( ctx->buffer + used, 0, 64 - used );
359
360 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
361 return( ret );
362
363 memset( ctx->buffer, 0, 56 );
364 }
365
366 /*
367 * Add message length
368 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 high = ( ctx->total[0] >> 29 )
370 | ( ctx->total[1] << 3 );
371 low = ( ctx->total[0] << 3 );
372
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200373 PUT_UINT32_BE( high, ctx->buffer, 56 );
374 PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200376 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100377 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100378
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200379 /*
380 * Output final state
381 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000382 PUT_UINT32_BE( ctx->state[0], output, 0 );
383 PUT_UINT32_BE( ctx->state[1], output, 4 );
384 PUT_UINT32_BE( ctx->state[2], output, 8 );
385 PUT_UINT32_BE( ctx->state[3], output, 12 );
386 PUT_UINT32_BE( ctx->state[4], output, 16 );
387 PUT_UINT32_BE( ctx->state[5], output, 20 );
388 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
390 if( ctx->is224 == 0 )
Paul Bakker5c2364c2012-10-01 14:41:15 +0000391 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100392
393 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000394}
395
Jaeden Amero041039f2018-02-19 15:28:08 +0000396#if !defined(MBEDTLS_DEPRECATED_REMOVED)
397void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
398 unsigned char output[32] )
399{
400 mbedtls_sha256_finish_ret( ctx, output );
401}
402#endif
403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200405
Paul Bakker5121ce52009-01-03 21:22:43 +0000406/*
407 * output = SHA-256( input buffer )
408 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100409int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100410 size_t ilen,
411 unsigned char output[32],
412 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000413{
Janos Follath24eed8d2019-11-22 13:21:35 +0000414 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
Hanno Becker8d215e72018-12-18 17:53:21 +0000417 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
418 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
419 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100422
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100423 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100424 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100425
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100426 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100427 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100428
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100429 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100430 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100431
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100432exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100434
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100435 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000436}
437
Jaeden Amero041039f2018-02-19 15:28:08 +0000438#if !defined(MBEDTLS_DEPRECATED_REMOVED)
439void mbedtls_sha256( const unsigned char *input,
440 size_t ilen,
441 unsigned char output[32],
442 int is224 )
443{
444 mbedtls_sha256_ret( input, ilen, output, is224 );
445}
446#endif
447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000449/*
450 * FIPS-180-2 test vectors
451 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000452static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000453{
454 { "abc" },
455 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
456 { "" }
457};
458
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100459static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000460{
461 3, 56, 1000
462};
463
Paul Bakker9e36f042013-06-30 14:34:05 +0200464static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000465{
466 /*
467 * SHA-224 test vectors
468 */
469 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
470 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
471 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
472 0xE3, 0x6C, 0x9D, 0xA7 },
473 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
474 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
475 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
476 0x52, 0x52, 0x25, 0x25 },
477 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
478 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
479 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
480 0x4E, 0xE7, 0xAD, 0x67 },
481
482 /*
483 * SHA-256 test vectors
484 */
485 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
486 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
487 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
488 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
489 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
490 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
491 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
492 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
493 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
494 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
495 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
496 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
497};
498
499/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000500 * Checkup routine
501 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000503{
Paul Bakker5b4af392014-06-26 12:09:34 +0200504 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500505 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200506 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
Russ Butlerbb83b422016-10-12 17:36:50 -0500509 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
510 if( NULL == buf )
511 {
512 if( verbose != 0 )
513 mbedtls_printf( "Buffer allocation failed\n" );
514
515 return( 1 );
516 }
517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200519
Paul Bakker5121ce52009-01-03 21:22:43 +0000520 for( i = 0; i < 6; i++ )
521 {
522 j = i % 3;
523 k = i < 3;
524
525 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100528 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100529 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000530
531 if( j == 2 )
532 {
533 memset( buf, 'a', buflen = 1000 );
534
535 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100536 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100537 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100538 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100539 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100540 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100541
Paul Bakker5121ce52009-01-03 21:22:43 +0000542 }
543 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100544 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100545 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100546 sha256_test_buflen[j] );
547 if( ret != 0 )
548 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100549 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100551 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100552 goto fail;
553
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
Paul Bakker9e36f042013-06-30 14:34:05 +0200555 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100556 {
557 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100558 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100559 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000563 }
564
565 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100568 goto exit;
569
570fail:
571 if( verbose != 0 )
572 mbedtls_printf( "failed\n" );
573
Paul Bakker5b4af392014-06-26 12:09:34 +0200574exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500576 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200577
578 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000579}
580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583#endif /* MBEDTLS_SHA256_C */