blob: 785e28b57378c863561112fbf9feb0d02321f16e [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
Hanno Becker2f6de422018-12-20 10:22:32 +000052#define SHA256_VALIDATE_RET(cond) \
53 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
54#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
55
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020056#if !defined(MBEDTLS_SHA256_ALT)
57
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020059{
Hanno Becker8d215e72018-12-18 17:53:21 +000060 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000061
Manuel Pégourié-Gonnard99419332019-10-03 10:40:57 +020062 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020063}
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020066{
67 if( ctx == NULL )
68 return;
69
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050070 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020071}
72
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020073void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
74 const mbedtls_sha256_context *src )
75{
Hanno Becker8d215e72018-12-18 17:53:21 +000076 SHA256_VALIDATE( dst != NULL );
77 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000078
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020079 *dst = *src;
80}
81
Paul Bakker5121ce52009-01-03 21:22:43 +000082/*
83 * SHA-256 context setup
84 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010085int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +000086{
Hanno Becker8d215e72018-12-18 17:53:21 +000087 SHA256_VALIDATE_RET( ctx != NULL );
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +020088#if defined(MBEDTLS_SHA256_NO_SHA224)
89 SHA256_VALIDATE_RET( is224 == 0 );
90 (void) is224;
91#else
Hanno Becker8d215e72018-12-18 17:53:21 +000092 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +020093#endif
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000094
Paul Bakker5121ce52009-01-03 21:22:43 +000095 ctx->total[0] = 0;
96 ctx->total[1] = 0;
97
Manuel Pégourié-Gonnardefd34482019-09-02 14:41:19 +020098#if !defined(MBEDTLS_SHA256_NO_SHA224)
99 ctx->is224 = is224;
100
101 if( is224 == 1 )
102 {
103 /* SHA-224 */
104 ctx->state[0] = 0xC1059ED8;
105 ctx->state[1] = 0x367CD507;
106 ctx->state[2] = 0x3070DD17;
107 ctx->state[3] = 0xF70E5939;
108 ctx->state[4] = 0xFFC00B31;
109 ctx->state[5] = 0x68581511;
110 ctx->state[6] = 0x64F98FA7;
111 ctx->state[7] = 0xBEFA4FA4;
112 }
113 else
114#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000115 {
116 /* SHA-256 */
117 ctx->state[0] = 0x6A09E667;
118 ctx->state[1] = 0xBB67AE85;
119 ctx->state[2] = 0x3C6EF372;
120 ctx->state[3] = 0xA54FF53A;
121 ctx->state[4] = 0x510E527F;
122 ctx->state[5] = 0x9B05688C;
123 ctx->state[6] = 0x1F83D9AB;
124 ctx->state[7] = 0x5BE0CD19;
125 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100126
127 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000128}
129
Jaeden Amero041039f2018-02-19 15:28:08 +0000130#if !defined(MBEDTLS_DEPRECATED_REMOVED)
131void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
132 int is224 )
133{
134 mbedtls_sha256_starts_ret( ctx, is224 );
135}
136#endif
137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200139static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000140{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200141 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
142 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
143 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
144 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
145 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
146 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
147 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
148 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
149 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
150 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
151 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
152 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
153 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
154 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
155 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
156 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
157};
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
Hanno Beckerd6028a12018-10-15 12:01:35 +0100159#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
160#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000161
162#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
163#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
164
165#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
166#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
167
Hanno Beckerd6028a12018-10-15 12:01:35 +0100168#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
169#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
171#define R(t) \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100172 ( \
173 W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
174 S0(W[(t) - 15]) + W[(t) - 16] \
175 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000176
Hanno Beckerd6028a12018-10-15 12:01:35 +0100177#define P(a,b,c,d,e,f,g,h,x,K) \
178 do \
179 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100180 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
181 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100182 (d) += temp1; (h) = temp1 + temp2; \
183 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000184
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100185int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100186 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200187{
188 uint32_t temp1, temp2, W[64];
189 uint32_t A[8];
190 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000191
Hanno Becker8d215e72018-12-18 17:53:21 +0000192 SHA256_VALIDATE_RET( ctx != NULL );
193 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000194
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200195 for( i = 0; i < 8; i++ )
196 A[i] = ctx->state[i];
197
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200198#if defined(MBEDTLS_SHA256_SMALLER)
199 for( i = 0; i < 64; i++ )
200 {
201 if( i < 16 )
Arto Kinnunen4f4849a2019-09-09 10:21:18 +0300202 W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200203 else
204 R( i );
205
206 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
207
208 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
209 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
210 }
211#else /* MBEDTLS_SHA256_SMALLER */
212 for( i = 0; i < 16; i++ )
Arto Kinnunen4f4849a2019-09-09 10:21:18 +0300213 W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200214
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200215 for( i = 0; i < 16; i += 8 )
216 {
217 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
218 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
219 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
220 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
221 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
222 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
223 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
224 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
225 }
226
227 for( i = 16; i < 64; i += 8 )
228 {
229 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
230 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
231 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
232 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
233 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
234 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
235 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
236 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
237 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200238#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200239
240 for( i = 0; i < 8; i++ )
241 ctx->state[i] += A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100242
243 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000244}
Jaeden Amero041039f2018-02-19 15:28:08 +0000245
246#if !defined(MBEDTLS_DEPRECATED_REMOVED)
247void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
248 const unsigned char data[64] )
249{
250 mbedtls_internal_sha256_process( ctx, data );
251}
252#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255/*
256 * SHA-256 process buffer
257 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100258int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100259 const unsigned char *input,
260 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000261{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100262 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000263 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000264 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000265
Hanno Becker8d215e72018-12-18 17:53:21 +0000266 SHA256_VALIDATE_RET( ctx != NULL );
267 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000268
Brian White12895d12014-04-11 11:29:42 -0400269 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100270 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000271
272 left = ctx->total[0] & 0x3F;
273 fill = 64 - left;
274
Paul Bakker5c2364c2012-10-01 14:41:15 +0000275 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000276 ctx->total[0] &= 0xFFFFFFFF;
277
Paul Bakker5c2364c2012-10-01 14:41:15 +0000278 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 ctx->total[1]++;
280
281 if( left && ilen >= fill )
282 {
Teppo Järvelin91d79382019-10-02 09:09:31 +0300283 mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100284
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100285 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100286 return( ret );
287
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 input += fill;
289 ilen -= fill;
290 left = 0;
291 }
292
293 while( ilen >= 64 )
294 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100295 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100296 return( ret );
297
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 input += 64;
299 ilen -= 64;
300 }
301
302 if( ilen > 0 )
Teppo Järvelin91d79382019-10-02 09:09:31 +0300303 mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100304
305 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000306}
307
Jaeden Amero041039f2018-02-19 15:28:08 +0000308#if !defined(MBEDTLS_DEPRECATED_REMOVED)
309void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
310 const unsigned char *input,
311 size_t ilen )
312{
313 mbedtls_sha256_update_ret( ctx, input, ilen );
314}
315#endif
316
Paul Bakker5121ce52009-01-03 21:22:43 +0000317/*
318 * SHA-256 final digest
319 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100320int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100321 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000322{
Arto Kinnunen9b3b1942019-09-09 17:02:35 +0300323 int ret, s_pos, o_pos;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200324 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000325 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
Hanno Becker8d215e72018-12-18 17:53:21 +0000327 SHA256_VALIDATE_RET( ctx != NULL );
328 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000329
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200330 /*
331 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
332 */
333 used = ctx->total[0] & 0x3F;
334
335 ctx->buffer[used++] = 0x80;
336
337 if( used <= 56 )
338 {
339 /* Enough room for padding + length in current block */
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200340 mbedtls_platform_memset( ctx->buffer + used, 0, 56 - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200341 }
342 else
343 {
344 /* We'll need an extra block */
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200345 mbedtls_platform_memset( ctx->buffer + used, 0, 64 - used );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200346
347 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
348 return( ret );
349
Manuel Pégourié-Gonnard7a346b82019-10-02 14:47:01 +0200350 mbedtls_platform_memset( ctx->buffer, 0, 56 );
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200351 }
352
353 /*
354 * Add message length
355 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 high = ( ctx->total[0] >> 29 )
357 | ( ctx->total[1] << 3 );
358 low = ( ctx->total[0] << 3 );
359
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300360 (void)mbedtls_platform_put_uint32_be( ctx->buffer + 56, high );
361 (void)mbedtls_platform_put_uint32_be( ctx->buffer + 60, low );
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200363 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100364 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100365
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200366 /*
367 * Output final state
368 */
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300369
Arto Kinnunen9b3b1942019-09-09 17:02:35 +0300370 for( s_pos = 0, o_pos = 0; s_pos < 7; s_pos++, o_pos += 4 )
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300371 {
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300372 (void)mbedtls_platform_put_uint32_be( &output[o_pos],
373 ctx->state[s_pos] );
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300374 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200376#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000377 if( ctx->is224 == 0 )
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200378#endif
Arto Kinnunen3d7439e2019-09-10 11:30:40 +0300379 (void)mbedtls_platform_put_uint32_be( &output[28], ctx->state[7] );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100380
381 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000382}
383
Jaeden Amero041039f2018-02-19 15:28:08 +0000384#if !defined(MBEDTLS_DEPRECATED_REMOVED)
385void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
386 unsigned char output[32] )
387{
388 mbedtls_sha256_finish_ret( ctx, output );
389}
390#endif
391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200393
Paul Bakker5121ce52009-01-03 21:22:43 +0000394/*
395 * output = SHA-256( input buffer )
396 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100397int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100398 size_t ilen,
399 unsigned char output[32],
400 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000401{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100402 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
Hanno Becker8d215e72018-12-18 17:53:21 +0000405 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
406 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
407 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000408
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100410
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100411 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100412 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100413
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100414 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100415 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100416
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100417 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100418 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100419
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100420exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100422
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100423 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424}
425
Jaeden Amero041039f2018-02-19 15:28:08 +0000426#if !defined(MBEDTLS_DEPRECATED_REMOVED)
427void mbedtls_sha256( const unsigned char *input,
428 size_t ilen,
429 unsigned char output[32],
430 int is224 )
431{
432 mbedtls_sha256_ret( input, ilen, output, is224 );
433}
434#endif
435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000437/*
438 * FIPS-180-2 test vectors
439 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000440static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000441{
442 { "abc" },
443 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
444 { "" }
445};
446
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100447static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000448{
449 3, 56, 1000
450};
451
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200452static const unsigned char sha256_test_sum[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000453{
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200454#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 /*
456 * SHA-224 test vectors
457 */
458 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
459 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
460 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
461 0xE3, 0x6C, 0x9D, 0xA7 },
462 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
463 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
464 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
465 0x52, 0x52, 0x25, 0x25 },
466 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
467 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
468 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
469 0x4E, 0xE7, 0xAD, 0x67 },
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200470#endif /* !MBEDTLS_SHA256_NO_SHA224 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
472 /*
473 * SHA-256 test vectors
474 */
475 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
476 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
477 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
478 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
479 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
480 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
481 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
482 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
483 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
484 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
485 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
486 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
487};
488
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200489#define SHA256_TEST_SUM_N \
490 ( sizeof( sha256_test_sum ) / sizeof( sha256_test_sum[0] ) )
491
Paul Bakker5121ce52009-01-03 21:22:43 +0000492/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000493 * Checkup routine
494 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000496{
Paul Bakker5b4af392014-06-26 12:09:34 +0200497 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500498 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200499 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
Russ Butlerbb83b422016-10-12 17:36:50 -0500502 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
503 if( NULL == buf )
504 {
505 if( verbose != 0 )
506 mbedtls_printf( "Buffer allocation failed\n" );
507
508 return( 1 );
509 }
510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200512
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200513 for( i = 0; i < (int) SHA256_TEST_SUM_N; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000514 {
515 j = i % 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200516#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000517 k = i < 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200518#else
519 k = 0;
520#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000521
522 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100525 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100526 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
528 if( j == 2 )
529 {
Teppo Järvelind49d2b62019-10-30 13:48:12 +0200530 memset( buf, 'a', buflen = 1000 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
532 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100533 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100534 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100535 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100536 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100537 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100538
Paul Bakker5121ce52009-01-03 21:22:43 +0000539 }
540 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100541 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100542 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100543 sha256_test_buflen[j] );
544 if( ret != 0 )
545 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100546 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000547
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100548 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100549 goto fail;
550
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
Paul Bakker9e36f042013-06-30 14:34:05 +0200552 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100553 {
554 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100555 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100556 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
558 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560 }
561
562 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100565 goto exit;
566
567fail:
568 if( verbose != 0 )
569 mbedtls_printf( "failed\n" );
570
Paul Bakker5b4af392014-06-26 12:09:34 +0200571exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500573 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200574
575 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000576}
577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580#endif /* MBEDTLS_SHA256_C */