blob: c576a034694628f569526bf6fd685333f9f0aded [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 );
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +0200116#if defined(MBEDTLS_SHA256_NO_SHA224)
117 SHA256_VALIDATE_RET( is224 == 0 );
118 (void) is224;
119#else
Hanno Becker8d215e72018-12-18 17:53:21 +0000120 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +0200121#endif
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000122
Paul Bakker5121ce52009-01-03 21:22:43 +0000123 ctx->total[0] = 0;
124 ctx->total[1] = 0;
125
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +0200126#if !defined(MBEDTLS_SHA256_NO_SHA224)
127 ctx->is224 = is224;
128
129 if( is224 == 1 )
130 {
131 /* SHA-224 */
132 ctx->state[0] = 0xC1059ED8;
133 ctx->state[1] = 0x367CD507;
134 ctx->state[2] = 0x3070DD17;
135 ctx->state[3] = 0xF70E5939;
136 ctx->state[4] = 0xFFC00B31;
137 ctx->state[5] = 0x68581511;
138 ctx->state[6] = 0x64F98FA7;
139 ctx->state[7] = 0xBEFA4FA4;
140 }
141 else
142#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000143 {
144 /* SHA-256 */
145 ctx->state[0] = 0x6A09E667;
146 ctx->state[1] = 0xBB67AE85;
147 ctx->state[2] = 0x3C6EF372;
148 ctx->state[3] = 0xA54FF53A;
149 ctx->state[4] = 0x510E527F;
150 ctx->state[5] = 0x9B05688C;
151 ctx->state[6] = 0x1F83D9AB;
152 ctx->state[7] = 0x5BE0CD19;
153 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100154
155 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000156}
157
Jaeden Amero041039f2018-02-19 15:28:08 +0000158#if !defined(MBEDTLS_DEPRECATED_REMOVED)
159void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
160 int is224 )
161{
162 mbedtls_sha256_starts_ret( ctx, is224 );
163}
164#endif
165
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200166#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200167static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000168{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200169 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
170 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
171 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
172 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
173 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
174 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
175 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
176 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
177 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
178 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
179 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
180 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
181 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
182 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
183 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
184 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
185};
Paul Bakker5121ce52009-01-03 21:22:43 +0000186
Hanno Beckerd6028a12018-10-15 12:01:35 +0100187#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
188#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000189
190#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
191#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
192
193#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
194#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
195
Hanno Beckerd6028a12018-10-15 12:01:35 +0100196#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
197#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000198
199#define R(t) \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100200 ( \
201 W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
202 S0(W[(t) - 15]) + W[(t) - 16] \
203 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000204
Hanno Beckerd6028a12018-10-15 12:01:35 +0100205#define P(a,b,c,d,e,f,g,h,x,K) \
206 do \
207 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100208 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
209 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100210 (d) += temp1; (h) = temp1 + temp2; \
211 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000212
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100213int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100214 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200215{
216 uint32_t temp1, temp2, W[64];
217 uint32_t A[8];
218 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
Hanno Becker8d215e72018-12-18 17:53:21 +0000220 SHA256_VALIDATE_RET( ctx != NULL );
221 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000222
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200223 for( i = 0; i < 8; i++ )
224 A[i] = ctx->state[i];
225
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200226#if defined(MBEDTLS_SHA256_SMALLER)
227 for( i = 0; i < 64; i++ )
228 {
229 if( i < 16 )
230 GET_UINT32_BE( W[i], data, 4 * i );
231 else
232 R( i );
233
234 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
235
236 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
237 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
238 }
239#else /* MBEDTLS_SHA256_SMALLER */
240 for( i = 0; i < 16; i++ )
241 GET_UINT32_BE( W[i], data, 4 * i );
242
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200243 for( i = 0; i < 16; i += 8 )
244 {
245 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
246 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
247 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
248 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
249 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
250 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
251 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
252 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
253 }
254
255 for( i = 16; i < 64; i += 8 )
256 {
257 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
258 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
259 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
260 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
261 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
262 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
263 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
264 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
265 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200266#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200267
268 for( i = 0; i < 8; i++ )
269 ctx->state[i] += A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100270
271 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000272}
Jaeden Amero041039f2018-02-19 15:28:08 +0000273
274#if !defined(MBEDTLS_DEPRECATED_REMOVED)
275void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
276 const unsigned char data[64] )
277{
278 mbedtls_internal_sha256_process( ctx, data );
279}
280#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
283/*
284 * SHA-256 process buffer
285 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100286int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100287 const unsigned char *input,
288 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000289{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100290 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000291 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000292 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000293
Hanno Becker8d215e72018-12-18 17:53:21 +0000294 SHA256_VALIDATE_RET( ctx != NULL );
295 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000296
Brian White12895d12014-04-11 11:29:42 -0400297 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100298 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
300 left = ctx->total[0] & 0x3F;
301 fill = 64 - left;
302
Paul Bakker5c2364c2012-10-01 14:41:15 +0000303 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000304 ctx->total[0] &= 0xFFFFFFFF;
305
Paul Bakker5c2364c2012-10-01 14:41:15 +0000306 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000307 ctx->total[1]++;
308
309 if( left && ilen >= fill )
310 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200311 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100312
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100313 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100314 return( ret );
315
Paul Bakker5121ce52009-01-03 21:22:43 +0000316 input += fill;
317 ilen -= fill;
318 left = 0;
319 }
320
321 while( ilen >= 64 )
322 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100323 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100324 return( ret );
325
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 input += 64;
327 ilen -= 64;
328 }
329
330 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200331 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100332
333 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000334}
335
Jaeden Amero041039f2018-02-19 15:28:08 +0000336#if !defined(MBEDTLS_DEPRECATED_REMOVED)
337void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
338 const unsigned char *input,
339 size_t ilen )
340{
341 mbedtls_sha256_update_ret( ctx, input, ilen );
342}
343#endif
344
Paul Bakker5121ce52009-01-03 21:22:43 +0000345/*
346 * SHA-256 final digest
347 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100348int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100349 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000350{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100351 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200352 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000353 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
Hanno Becker8d215e72018-12-18 17:53:21 +0000355 SHA256_VALIDATE_RET( ctx != NULL );
356 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000357
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200358 /*
359 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
360 */
361 used = ctx->total[0] & 0x3F;
362
363 ctx->buffer[used++] = 0x80;
364
365 if( used <= 56 )
366 {
367 /* Enough room for padding + length in current block */
368 memset( ctx->buffer + used, 0, 56 - used );
369 }
370 else
371 {
372 /* We'll need an extra block */
373 memset( ctx->buffer + used, 0, 64 - used );
374
375 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
376 return( ret );
377
378 memset( ctx->buffer, 0, 56 );
379 }
380
381 /*
382 * Add message length
383 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 high = ( ctx->total[0] >> 29 )
385 | ( ctx->total[1] << 3 );
386 low = ( ctx->total[0] << 3 );
387
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +0200388 sha256_put_uint32_be( high, ctx->buffer, 56 );
389 sha256_put_uint32_be( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200391 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100392 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100393
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200394 /*
395 * Output final state
396 */
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +0200397 sha256_put_uint32_be( ctx->state[0], output, 0 );
398 sha256_put_uint32_be( ctx->state[1], output, 4 );
399 sha256_put_uint32_be( ctx->state[2], output, 8 );
400 sha256_put_uint32_be( ctx->state[3], output, 12 );
401 sha256_put_uint32_be( ctx->state[4], output, 16 );
402 sha256_put_uint32_be( ctx->state[5], output, 20 );
403 sha256_put_uint32_be( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200405#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 if( ctx->is224 == 0 )
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200407#endif
Manuel Pégourié-Gonnard100c0572019-07-17 12:15:05 +0200408 sha256_put_uint32_be( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100409
410 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411}
412
Jaeden Amero041039f2018-02-19 15:28:08 +0000413#if !defined(MBEDTLS_DEPRECATED_REMOVED)
414void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
415 unsigned char output[32] )
416{
417 mbedtls_sha256_finish_ret( ctx, output );
418}
419#endif
420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200422
Paul Bakker5121ce52009-01-03 21:22:43 +0000423/*
424 * output = SHA-256( input buffer )
425 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100426int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100427 size_t ilen,
428 unsigned char output[32],
429 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000430{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100431 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Hanno Becker8d215e72018-12-18 17:53:21 +0000434 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
435 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
436 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100439
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100440 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100441 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100442
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100443 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100444 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100445
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100446 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100447 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100448
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100449exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100451
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100452 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000453}
454
Jaeden Amero041039f2018-02-19 15:28:08 +0000455#if !defined(MBEDTLS_DEPRECATED_REMOVED)
456void mbedtls_sha256( const unsigned char *input,
457 size_t ilen,
458 unsigned char output[32],
459 int is224 )
460{
461 mbedtls_sha256_ret( input, ilen, output, is224 );
462}
463#endif
464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000466/*
467 * FIPS-180-2 test vectors
468 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000469static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000470{
471 { "abc" },
472 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
473 { "" }
474};
475
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100476static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000477{
478 3, 56, 1000
479};
480
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200481static const unsigned char sha256_test_sum[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000482{
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200483#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000484 /*
485 * SHA-224 test vectors
486 */
487 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
488 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
489 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
490 0xE3, 0x6C, 0x9D, 0xA7 },
491 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
492 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
493 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
494 0x52, 0x52, 0x25, 0x25 },
495 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
496 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
497 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
498 0x4E, 0xE7, 0xAD, 0x67 },
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200499#endif /* !MBEDTLS_SHA256_NO_SHA224 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
501 /*
502 * SHA-256 test vectors
503 */
504 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
505 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
506 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
507 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
508 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
509 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
510 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
511 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
512 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
513 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
514 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
515 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
516};
517
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200518#define SHA256_TEST_SUM_N \
519 ( sizeof( sha256_test_sum ) / sizeof( sha256_test_sum[0] ) )
520
Paul Bakker5121ce52009-01-03 21:22:43 +0000521/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 * Checkup routine
523 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000525{
Paul Bakker5b4af392014-06-26 12:09:34 +0200526 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500527 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200528 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000530
Russ Butlerbb83b422016-10-12 17:36:50 -0500531 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
532 if( NULL == buf )
533 {
534 if( verbose != 0 )
535 mbedtls_printf( "Buffer allocation failed\n" );
536
537 return( 1 );
538 }
539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200541
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200542 for( i = 0; i < (int) SHA256_TEST_SUM_N; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000543 {
544 j = i % 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200545#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 k = i < 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200547#else
548 k = 0;
549#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
551 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000553
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100554 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100555 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000556
557 if( j == 2 )
558 {
559 memset( buf, 'a', buflen = 1000 );
560
561 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100562 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100563 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100564 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100565 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100566 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100567
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 }
569 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100570 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100571 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100572 sha256_test_buflen[j] );
573 if( ret != 0 )
574 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100575 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100577 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100578 goto fail;
579
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Paul Bakker9e36f042013-06-30 14:34:05 +0200581 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100582 {
583 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100584 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100585 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000586
587 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 }
590
591 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100594 goto exit;
595
596fail:
597 if( verbose != 0 )
598 mbedtls_printf( "failed\n" );
599
Paul Bakker5b4af392014-06-26 12:09:34 +0200600exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500602 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200603
604 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000605}
606
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609#endif /* MBEDTLS_SHA256_C */