blob: 1c1df0257a1ac176eaaa652f961f672ec7898b70 [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é-Gonnard2cf5a7c2015-04-08 12:49:31 +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 Kinnunen0b62ce82019-09-04 14:04:57 +0300202 W[i] = 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 Kinnunen0b62ce82019-09-04 14:04:57 +0300213 W[i] = 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 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200283 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 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200303 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{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100323 int ret;
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 */
340 memset( ctx->buffer + used, 0, 56 - used );
341 }
342 else
343 {
344 /* We'll need an extra block */
345 memset( ctx->buffer + used, 0, 64 - used );
346
347 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
348 return( ret );
349
350 memset( ctx->buffer, 0, 56 );
351 }
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 Kinnunen0b62ce82019-09-04 14:04:57 +0300360 mbedtls_platform_put_uint32_be( ctx->buffer + 56, high );
361 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
370 for ( int s_pos = 0, o_pos = 0; s_pos < 7; s_pos++, o_pos += 4 )
371 {
372 mbedtls_platform_put_uint32_be( &output[o_pos], ctx->state[s_pos] );
373 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200375#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 if( ctx->is224 == 0 )
Manuel Pégourié-Gonnard8463d292019-07-16 14:39:55 +0200377#endif
Arto Kinnunen0b62ce82019-09-04 14:04:57 +0300378 mbedtls_platform_put_uint32_be( &output[28], ctx->state[7] );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100379
380 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000381}
382
Jaeden Amero041039f2018-02-19 15:28:08 +0000383#if !defined(MBEDTLS_DEPRECATED_REMOVED)
384void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
385 unsigned char output[32] )
386{
387 mbedtls_sha256_finish_ret( ctx, output );
388}
389#endif
390
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200392
Paul Bakker5121ce52009-01-03 21:22:43 +0000393/*
394 * output = SHA-256( input buffer )
395 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100396int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100397 size_t ilen,
398 unsigned char output[32],
399 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000400{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100401 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
Hanno Becker8d215e72018-12-18 17:53:21 +0000404 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
405 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
406 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000407
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100409
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100410 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100411 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100412
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100413 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100414 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100415
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100416 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100417 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100418
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100419exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100421
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100422 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000423}
424
Jaeden Amero041039f2018-02-19 15:28:08 +0000425#if !defined(MBEDTLS_DEPRECATED_REMOVED)
426void mbedtls_sha256( const unsigned char *input,
427 size_t ilen,
428 unsigned char output[32],
429 int is224 )
430{
431 mbedtls_sha256_ret( input, ilen, output, is224 );
432}
433#endif
434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000436/*
437 * FIPS-180-2 test vectors
438 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000439static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000440{
441 { "abc" },
442 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
443 { "" }
444};
445
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100446static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000447{
448 3, 56, 1000
449};
450
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200451static const unsigned char sha256_test_sum[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000452{
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200453#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000454 /*
455 * SHA-224 test vectors
456 */
457 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
458 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
459 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
460 0xE3, 0x6C, 0x9D, 0xA7 },
461 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
462 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
463 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
464 0x52, 0x52, 0x25, 0x25 },
465 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
466 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
467 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
468 0x4E, 0xE7, 0xAD, 0x67 },
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200469#endif /* !MBEDTLS_SHA256_NO_SHA224 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
471 /*
472 * SHA-256 test vectors
473 */
474 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
475 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
476 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
477 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
478 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
479 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
480 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
481 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
482 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
483 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
484 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
485 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
486};
487
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200488#define SHA256_TEST_SUM_N \
489 ( sizeof( sha256_test_sum ) / sizeof( sha256_test_sum[0] ) )
490
Paul Bakker5121ce52009-01-03 21:22:43 +0000491/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000492 * Checkup routine
493 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000495{
Paul Bakker5b4af392014-06-26 12:09:34 +0200496 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500497 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200498 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
Russ Butlerbb83b422016-10-12 17:36:50 -0500501 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
502 if( NULL == buf )
503 {
504 if( verbose != 0 )
505 mbedtls_printf( "Buffer allocation failed\n" );
506
507 return( 1 );
508 }
509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200511
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200512 for( i = 0; i < (int) SHA256_TEST_SUM_N; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000513 {
514 j = i % 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200515#if !defined(MBEDTLS_SHA256_NO_SHA224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 k = i < 3;
Manuel Pégourié-Gonnardabebdd12019-07-16 15:37:56 +0200517#else
518 k = 0;
519#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000520
521 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100524 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100525 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
527 if( j == 2 )
528 {
529 memset( buf, 'a', buflen = 1000 );
530
531 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100532 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100533 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100534 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100535 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100536 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100537
Paul Bakker5121ce52009-01-03 21:22:43 +0000538 }
539 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100540 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100541 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100542 sha256_test_buflen[j] );
543 if( ret != 0 )
544 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100545 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000546
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100547 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100548 goto fail;
549
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
Paul Bakker9e36f042013-06-30 14:34:05 +0200551 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100552 {
553 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100554 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100555 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000556
557 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000559 }
560
561 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100564 goto exit;
565
566fail:
567 if( verbose != 0 )
568 mbedtls_printf( "failed\n" );
569
Paul Bakker5b4af392014-06-26 12:09:34 +0200570exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500572 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200573
574 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000575}
576
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579#endif /* MBEDTLS_SHA256_C */