blob: a141511cda030069e64945f39fa4404860dda057 [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"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050045#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050047#define mbedtls_calloc calloc
48#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#endif /* MBEDTLS_PLATFORM_C */
50#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010051
Manuel Pégourié-Gonnard0cfb6ef2019-09-05 14:07:01 +020052#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
53 !defined(inline) && !defined(__cplusplus)
54#define inline __inline
55#endif
56
Hanno Becker2f6de422018-12-20 10:22:32 +000057#define SHA256_VALIDATE_RET(cond) \
58 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
59#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
60
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020061#if !defined(MBEDTLS_SHA256_ALT)
62
Paul Bakker5121ce52009-01-03 21:22:43 +000063/*
Manuel Pégourié-Gonnardc7abba32019-09-05 11:33:32 +020064 * 32-bit integer manipulation (big endian)
Paul Bakker5121ce52009-01-03 21:22:43 +000065 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000066#ifndef GET_UINT32_BE
67#define GET_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020068do { \
Paul Bakker5c2364c2012-10-01 14:41:15 +000069 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
70 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
71 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
72 | ( (uint32_t) (b)[(i) + 3] ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020073} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000074#endif
75
Manuel Pégourié-Gonnardc7abba32019-09-05 11:33:32 +020076static inline void sha256_put_uint32_be( uint32_t n,
77 unsigned char *b,
78 uint8_t i )
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +020079{
Manuel Pégourié-Gonnardc7abba32019-09-05 11:33:32 +020080 b[i ] = (unsigned char) ( n >> 24 );
81 b[i + 1] = (unsigned char) ( n >> 16 );
82 b[i + 2] = (unsigned char) ( n >> 8 );
83 b[i + 3] = (unsigned char) ( n );
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +020084}
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +020085
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020086void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020087{
Hanno Becker8d215e72018-12-18 17:53:21 +000088 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000089
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020090 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020091}
92
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020094{
95 if( ctx == NULL )
96 return;
97
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050098 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020099}
100
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200101void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
102 const mbedtls_sha256_context *src )
103{
Hanno Becker8d215e72018-12-18 17:53:21 +0000104 SHA256_VALIDATE( dst != NULL );
105 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000106
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200107 *dst = *src;
108}
109
Paul Bakker5121ce52009-01-03 21:22:43 +0000110/*
111 * SHA-256 context setup
112 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100113int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000114{
Hanno Becker8d215e72018-12-18 17:53:21 +0000115 SHA256_VALIDATE_RET( ctx != NULL );
116 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000117
Paul Bakker5121ce52009-01-03 21:22:43 +0000118 ctx->total[0] = 0;
119 ctx->total[1] = 0;
120
121 if( is224 == 0 )
122 {
123 /* SHA-256 */
124 ctx->state[0] = 0x6A09E667;
125 ctx->state[1] = 0xBB67AE85;
126 ctx->state[2] = 0x3C6EF372;
127 ctx->state[3] = 0xA54FF53A;
128 ctx->state[4] = 0x510E527F;
129 ctx->state[5] = 0x9B05688C;
130 ctx->state[6] = 0x1F83D9AB;
131 ctx->state[7] = 0x5BE0CD19;
132 }
133 else
134 {
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200135#if defined(MBEDTLS_SHA256_NO_SHA224)
136 return( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA );
137#else
Paul Bakker5121ce52009-01-03 21:22:43 +0000138 /* SHA-224 */
139 ctx->state[0] = 0xC1059ED8;
140 ctx->state[1] = 0x367CD507;
141 ctx->state[2] = 0x3070DD17;
142 ctx->state[3] = 0xF70E5939;
143 ctx->state[4] = 0xFFC00B31;
144 ctx->state[5] = 0x68581511;
145 ctx->state[6] = 0x64F98FA7;
146 ctx->state[7] = 0xBEFA4FA4;
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200147#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000148 }
149
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200150#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000151 ctx->is224 = is224;
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200152#endif
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100153
154 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000155}
156
Jaeden Amero041039f2018-02-19 15:28:08 +0000157#if !defined(MBEDTLS_DEPRECATED_REMOVED)
158void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
159 int is224 )
160{
161 mbedtls_sha256_starts_ret( ctx, is224 );
162}
163#endif
164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200166static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000167{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200168 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
169 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
170 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
171 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
172 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
173 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
174 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
175 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
176 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
177 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
178 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
179 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
180 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
181 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
182 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
183 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
184};
Paul Bakker5121ce52009-01-03 21:22:43 +0000185
Hanno Beckerd6028a12018-10-15 12:01:35 +0100186#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
187#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
189#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
190#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
191
192#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
193#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
194
Hanno Beckerd6028a12018-10-15 12:01:35 +0100195#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
196#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
198#define R(t) \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100199 ( \
200 W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
201 S0(W[(t) - 15]) + W[(t) - 16] \
202 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000203
Hanno Beckerd6028a12018-10-15 12:01:35 +0100204#define P(a,b,c,d,e,f,g,h,x,K) \
205 do \
206 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100207 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
208 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100209 (d) += temp1; (h) = temp1 + temp2; \
210 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000211
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100212int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100213 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200214{
215 uint32_t temp1, temp2, W[64];
216 uint32_t A[8];
217 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000218
Hanno Becker8d215e72018-12-18 17:53:21 +0000219 SHA256_VALIDATE_RET( ctx != NULL );
220 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000221
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200222 for( i = 0; i < 8; i++ )
223 A[i] = ctx->state[i];
224
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200225#if defined(MBEDTLS_SHA256_SMALLER)
226 for( i = 0; i < 64; i++ )
227 {
228 if( i < 16 )
229 GET_UINT32_BE( W[i], data, 4 * i );
230 else
231 R( i );
232
233 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
234
235 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
236 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
237 }
238#else /* MBEDTLS_SHA256_SMALLER */
239 for( i = 0; i < 16; i++ )
240 GET_UINT32_BE( W[i], data, 4 * i );
241
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200242 for( i = 0; i < 16; i += 8 )
243 {
244 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
245 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
246 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
247 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
248 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
249 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
250 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
251 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
252 }
253
254 for( i = 16; i < 64; i += 8 )
255 {
256 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
257 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
258 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
259 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
260 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
261 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
262 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
263 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
264 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200265#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200266
267 for( i = 0; i < 8; i++ )
268 ctx->state[i] += A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100269
270 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000271}
Jaeden Amero041039f2018-02-19 15:28:08 +0000272
273#if !defined(MBEDTLS_DEPRECATED_REMOVED)
274void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
275 const unsigned char data[64] )
276{
277 mbedtls_internal_sha256_process( ctx, data );
278}
279#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000281
282/*
283 * SHA-256 process buffer
284 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100285int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100286 const unsigned char *input,
287 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000288{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100289 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000290 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000291 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000292
Hanno Becker8d215e72018-12-18 17:53:21 +0000293 SHA256_VALIDATE_RET( ctx != NULL );
294 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000295
Brian White12895d12014-04-11 11:29:42 -0400296 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100297 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
299 left = ctx->total[0] & 0x3F;
300 fill = 64 - left;
301
Paul Bakker5c2364c2012-10-01 14:41:15 +0000302 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000303 ctx->total[0] &= 0xFFFFFFFF;
304
Paul Bakker5c2364c2012-10-01 14:41:15 +0000305 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000306 ctx->total[1]++;
307
308 if( left && ilen >= fill )
309 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200310 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100311
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100312 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100313 return( ret );
314
Paul Bakker5121ce52009-01-03 21:22:43 +0000315 input += fill;
316 ilen -= fill;
317 left = 0;
318 }
319
320 while( ilen >= 64 )
321 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100322 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100323 return( ret );
324
Paul Bakker5121ce52009-01-03 21:22:43 +0000325 input += 64;
326 ilen -= 64;
327 }
328
329 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200330 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100331
332 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333}
334
Jaeden Amero041039f2018-02-19 15:28:08 +0000335#if !defined(MBEDTLS_DEPRECATED_REMOVED)
336void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
337 const unsigned char *input,
338 size_t ilen )
339{
340 mbedtls_sha256_update_ret( ctx, input, ilen );
341}
342#endif
343
Paul Bakker5121ce52009-01-03 21:22:43 +0000344/*
345 * SHA-256 final digest
346 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100347int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100348 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000349{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100350 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200351 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000352 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
Hanno Becker8d215e72018-12-18 17:53:21 +0000354 SHA256_VALIDATE_RET( ctx != NULL );
355 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000356
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200357 /*
358 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
359 */
360 used = ctx->total[0] & 0x3F;
361
362 ctx->buffer[used++] = 0x80;
363
364 if( used <= 56 )
365 {
366 /* Enough room for padding + length in current block */
367 memset( ctx->buffer + used, 0, 56 - used );
368 }
369 else
370 {
371 /* We'll need an extra block */
372 memset( ctx->buffer + used, 0, 64 - used );
373
374 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
375 return( ret );
376
377 memset( ctx->buffer, 0, 56 );
378 }
379
380 /*
381 * Add message length
382 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 high = ( ctx->total[0] >> 29 )
384 | ( ctx->total[1] << 3 );
385 low = ( ctx->total[0] << 3 );
386
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +0200387 sha256_put_uint32_be( high, ctx->buffer, 56 );
388 sha256_put_uint32_be( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200390 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100391 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100392
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200393 /*
394 * Output final state
395 */
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +0200396 sha256_put_uint32_be( ctx->state[0], output, 0 );
397 sha256_put_uint32_be( ctx->state[1], output, 4 );
398 sha256_put_uint32_be( ctx->state[2], output, 8 );
399 sha256_put_uint32_be( ctx->state[3], output, 12 );
400 sha256_put_uint32_be( ctx->state[4], output, 16 );
401 sha256_put_uint32_be( ctx->state[5], output, 20 );
402 sha256_put_uint32_be( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200404#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 if( ctx->is224 == 0 )
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200406#endif
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +0200407 sha256_put_uint32_be( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100408
409 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410}
411
Jaeden Amero041039f2018-02-19 15:28:08 +0000412#if !defined(MBEDTLS_DEPRECATED_REMOVED)
413void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
414 unsigned char output[32] )
415{
416 mbedtls_sha256_finish_ret( ctx, output );
417}
418#endif
419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200421
Paul Bakker5121ce52009-01-03 21:22:43 +0000422/*
423 * output = SHA-256( input buffer )
424 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100425int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100426 size_t ilen,
427 unsigned char output[32],
428 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000429{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100430 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Hanno Becker8d215e72018-12-18 17:53:21 +0000433 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
434 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
435 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100438
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100439 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100440 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100441
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100442 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100443 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100444
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100445 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100446 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100447
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100448exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100450
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100451 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452}
453
Jaeden Amero041039f2018-02-19 15:28:08 +0000454#if !defined(MBEDTLS_DEPRECATED_REMOVED)
455void mbedtls_sha256( const unsigned char *input,
456 size_t ilen,
457 unsigned char output[32],
458 int is224 )
459{
460 mbedtls_sha256_ret( input, ilen, output, is224 );
461}
462#endif
463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000465/*
466 * FIPS-180-2 test vectors
467 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000468static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000469{
470 { "abc" },
471 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
472 { "" }
473};
474
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100475static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000476{
477 3, 56, 1000
478};
479
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200480static const unsigned char sha256_test_sum[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000481{
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200482#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000483 /*
484 * SHA-224 test vectors
485 */
486 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
487 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
488 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
489 0xE3, 0x6C, 0x9D, 0xA7 },
490 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
491 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
492 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
493 0x52, 0x52, 0x25, 0x25 },
494 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
495 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
496 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
497 0x4E, 0xE7, 0xAD, 0x67 },
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200498#endif /* !MBEDTLS_SHA256_NO_SHA224 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
500 /*
501 * SHA-256 test vectors
502 */
503 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
504 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
505 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
506 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
507 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
508 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
509 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
510 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
511 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
512 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
513 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
514 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
515};
516
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200517#define SHA256_TEST_SUM_N \
518 ( sizeof( sha256_test_sum ) / sizeof( sha256_test_sum[0] ) )
519
Paul Bakker5121ce52009-01-03 21:22:43 +0000520/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 * Checkup routine
522 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000524{
Paul Bakker5b4af392014-06-26 12:09:34 +0200525 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500526 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200527 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Russ Butlerbb83b422016-10-12 17:36:50 -0500530 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
531 if( NULL == buf )
532 {
533 if( verbose != 0 )
534 mbedtls_printf( "Buffer allocation failed\n" );
535
536 return( 1 );
537 }
538
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200540
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200541 for( i = 0; i < (int) SHA256_TEST_SUM_N; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000542 {
543 j = i % 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200544#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000545 k = i < 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200546#else
547 k = 0;
548#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
550 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100553 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100554 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 if( j == 2 )
557 {
558 memset( buf, 'a', buflen = 1000 );
559
560 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100561 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100562 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100563 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100564 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100565 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100566
Paul Bakker5121ce52009-01-03 21:22:43 +0000567 }
568 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100569 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100570 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100571 sha256_test_buflen[j] );
572 if( ret != 0 )
573 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100574 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100576 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100577 goto fail;
578
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Paul Bakker9e36f042013-06-30 14:34:05 +0200580 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100581 {
582 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100583 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100584 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
586 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000588 }
589
590 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000592
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100593 goto exit;
594
595fail:
596 if( verbose != 0 )
597 mbedtls_printf( "failed\n" );
598
Paul Bakker5b4af392014-06-26 12:09:34 +0200599exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500601 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200602
603 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000604}
605
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608#endif /* MBEDTLS_SHA256_C */