blob: 087302369866612dcb8cecaea3ef7dde0e32f595 [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
Paul Bakker9e36f042013-06-30 14:34:05 +0200480static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000481{
482 /*
483 * SHA-224 test vectors
484 */
485 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
486 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
487 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
488 0xE3, 0x6C, 0x9D, 0xA7 },
489 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
490 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
491 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
492 0x52, 0x52, 0x25, 0x25 },
493 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
494 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
495 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
496 0x4E, 0xE7, 0xAD, 0x67 },
497
498 /*
499 * SHA-256 test vectors
500 */
501 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
502 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
503 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
504 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
505 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
506 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
507 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
508 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
509 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
510 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
511 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
512 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
513};
514
515/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 * Checkup routine
517 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000519{
Paul Bakker5b4af392014-06-26 12:09:34 +0200520 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500521 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200522 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
Russ Butlerbb83b422016-10-12 17:36:50 -0500525 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
526 if( NULL == buf )
527 {
528 if( verbose != 0 )
529 mbedtls_printf( "Buffer allocation failed\n" );
530
531 return( 1 );
532 }
533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200535
Paul Bakker5121ce52009-01-03 21:22:43 +0000536 for( i = 0; i < 6; i++ )
537 {
538 j = i % 3;
539 k = i < 3;
540
541 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100544 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100545 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000546
547 if( j == 2 )
548 {
549 memset( buf, 'a', buflen = 1000 );
550
551 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100552 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100553 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100554 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100555 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100556 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100557
Paul Bakker5121ce52009-01-03 21:22:43 +0000558 }
559 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100560 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100561 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100562 sha256_test_buflen[j] );
563 if( ret != 0 )
564 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100565 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100567 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100568 goto fail;
569
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
Paul Bakker9e36f042013-06-30 14:34:05 +0200571 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100572 {
573 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100574 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100575 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
577 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 }
580
581 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100584 goto exit;
585
586fail:
587 if( verbose != 0 )
588 mbedtls_printf( "failed\n" );
589
Paul Bakker5b4af392014-06-26 12:09:34 +0200590exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500592 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200593
594 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000595}
596
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599#endif /* MBEDTLS_SHA256_C */