blob: 36ab0c1aa82158e481c4aa986f483070a954458c [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <string.h>
34
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_SELF_TEST)
36#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010038#else
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050040#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050042#define mbedtls_calloc calloc
43#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#endif /* MBEDTLS_PLATFORM_C */
45#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Hanno Becker2f6de422018-12-20 10:22:32 +000047#define SHA256_VALIDATE_RET(cond) \
48 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
49#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
50
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020051#if !defined(MBEDTLS_SHA256_ALT)
52
Paul Bakker5121ce52009-01-03 21:22:43 +000053/*
54 * 32-bit integer manipulation macros (big endian)
55 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000056#ifndef GET_UINT32_BE
57#define GET_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020058do { \
Paul Bakker5c2364c2012-10-01 14:41:15 +000059 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
60 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
61 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
62 | ( (uint32_t) (b)[(i) + 3] ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020063} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000064#endif
65
Paul Bakker5c2364c2012-10-01 14:41:15 +000066#ifndef PUT_UINT32_BE
67#define PUT_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020068do { \
Paul Bakker5121ce52009-01-03 21:22:43 +000069 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
70 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
71 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
72 (b)[(i) + 3] = (unsigned char) ( (n) ); \
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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020076void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020077{
Hanno Becker8d215e72018-12-18 17:53:21 +000078 SHA256_VALIDATE( ctx != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000079
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020081}
82
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020084{
85 if( ctx == NULL )
86 return;
87
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050088 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020089}
90
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020091void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
92 const mbedtls_sha256_context *src )
93{
Hanno Becker8d215e72018-12-18 17:53:21 +000094 SHA256_VALIDATE( dst != NULL );
95 SHA256_VALIDATE( src != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000096
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020097 *dst = *src;
98}
99
Paul Bakker5121ce52009-01-03 21:22:43 +0000100/*
101 * SHA-256 context setup
102 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100103int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
Hanno Becker8d215e72018-12-18 17:53:21 +0000105 SHA256_VALIDATE_RET( ctx != NULL );
106 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000107
Paul Bakker5121ce52009-01-03 21:22:43 +0000108 ctx->total[0] = 0;
109 ctx->total[1] = 0;
110
111 if( is224 == 0 )
112 {
113 /* SHA-256 */
114 ctx->state[0] = 0x6A09E667;
115 ctx->state[1] = 0xBB67AE85;
116 ctx->state[2] = 0x3C6EF372;
117 ctx->state[3] = 0xA54FF53A;
118 ctx->state[4] = 0x510E527F;
119 ctx->state[5] = 0x9B05688C;
120 ctx->state[6] = 0x1F83D9AB;
121 ctx->state[7] = 0x5BE0CD19;
122 }
123 else
124 {
125 /* SHA-224 */
126 ctx->state[0] = 0xC1059ED8;
127 ctx->state[1] = 0x367CD507;
128 ctx->state[2] = 0x3070DD17;
129 ctx->state[3] = 0xF70E5939;
130 ctx->state[4] = 0xFFC00B31;
131 ctx->state[5] = 0x68581511;
132 ctx->state[6] = 0x64F98FA7;
133 ctx->state[7] = 0xBEFA4FA4;
134 }
135
136 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100137
138 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000139}
140
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200142static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000143{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200144 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
145 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
146 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
147 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
148 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
149 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
150 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
151 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
152 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
153 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
154 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
155 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
156 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
157 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
158 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
159 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
160};
Paul Bakker5121ce52009-01-03 21:22:43 +0000161
Hanno Becker1eeca412018-10-15 12:01:35 +0100162#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
163#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
165#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
166#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
167
168#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
169#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
170
Hanno Becker1eeca412018-10-15 12:01:35 +0100171#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
172#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000173
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200174#define R(t) \
175 ( \
176 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
177 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100178 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000179
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200180#define P(a,b,c,d,e,f,g,h,x,K) \
181 do \
182 { \
183 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
184 local.temp2 = S2(a) + F0((a),(b),(c)); \
185 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100186 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000187
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100188int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100189 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200190{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200191 struct
192 {
193 uint32_t temp1, temp2, W[64];
194 uint32_t A[8];
195 } local;
196
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200197 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000198
Hanno Becker8d215e72018-12-18 17:53:21 +0000199 SHA256_VALIDATE_RET( ctx != NULL );
200 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000201
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200202 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200203 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200204
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200205#if defined(MBEDTLS_SHA256_SMALLER)
206 for( i = 0; i < 64; i++ )
207 {
208 if( i < 16 )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200209 GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200210 else
211 R( i );
212
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200213 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
214 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200215
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200216 local.temp1 = local.A[7]; local.A[7] = local.A[6];
217 local.A[6] = local.A[5]; local.A[5] = local.A[4];
218 local.A[4] = local.A[3]; local.A[3] = local.A[2];
219 local.A[2] = local.A[1]; local.A[1] = local.A[0];
220 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200221 }
222#else /* MBEDTLS_SHA256_SMALLER */
223 for( i = 0; i < 16; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200224 GET_UINT32_BE( local.W[i], data, 4 * i );
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200225
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200226 for( i = 0; i < 16; i += 8 )
227 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200228 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
229 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
230 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
231 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
232 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
233 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
234 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
235 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
236 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
237 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
238 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
239 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
240 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
241 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
242 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
243 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200244 }
245
246 for( i = 16; i < 64; i += 8 )
247 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200248 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
249 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
250 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
251 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
252 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
253 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
254 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
255 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
256 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
257 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
258 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
259 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
260 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
261 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
262 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
263 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200264 }
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++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200268 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100269
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200270 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200271 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100272
273 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000274}
Jaeden Amero041039f2018-02-19 15:28:08 +0000275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000277
278/*
279 * SHA-256 process buffer
280 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100281int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100282 const unsigned char *input,
283 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000284{
Janos Follath24eed8d2019-11-22 13:21:35 +0000285 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000286 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000287 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000288
Hanno Becker8d215e72018-12-18 17:53:21 +0000289 SHA256_VALIDATE_RET( ctx != NULL );
290 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Becker596e0142018-12-18 15:00:38 +0000291
Brian White12895d12014-04-11 11:29:42 -0400292 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100293 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000294
295 left = ctx->total[0] & 0x3F;
296 fill = 64 - left;
297
Paul Bakker5c2364c2012-10-01 14:41:15 +0000298 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 ctx->total[0] &= 0xFFFFFFFF;
300
Paul Bakker5c2364c2012-10-01 14:41:15 +0000301 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000302 ctx->total[1]++;
303
304 if( left && ilen >= fill )
305 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200306 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100307
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100308 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100309 return( ret );
310
Paul Bakker5121ce52009-01-03 21:22:43 +0000311 input += fill;
312 ilen -= fill;
313 left = 0;
314 }
315
316 while( ilen >= 64 )
317 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100318 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100319 return( ret );
320
Paul Bakker5121ce52009-01-03 21:22:43 +0000321 input += 64;
322 ilen -= 64;
323 }
324
325 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200326 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100327
328 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329}
330
Paul Bakker5121ce52009-01-03 21:22:43 +0000331/*
332 * SHA-256 final digest
333 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100334int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200335 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000336{
Janos Follath24eed8d2019-11-22 13:21:35 +0000337 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200338 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000339 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
Hanno Becker8d215e72018-12-18 17:53:21 +0000341 SHA256_VALIDATE_RET( ctx != NULL );
342 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000343
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200344 /*
345 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
346 */
347 used = ctx->total[0] & 0x3F;
348
349 ctx->buffer[used++] = 0x80;
350
351 if( used <= 56 )
352 {
353 /* Enough room for padding + length in current block */
354 memset( ctx->buffer + used, 0, 56 - used );
355 }
356 else
357 {
358 /* We'll need an extra block */
359 memset( ctx->buffer + used, 0, 64 - used );
360
361 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
362 return( ret );
363
364 memset( ctx->buffer, 0, 56 );
365 }
366
367 /*
368 * Add message length
369 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000370 high = ( ctx->total[0] >> 29 )
371 | ( ctx->total[1] << 3 );
372 low = ( ctx->total[0] << 3 );
373
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200374 PUT_UINT32_BE( high, ctx->buffer, 56 );
375 PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200377 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100378 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100379
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200380 /*
381 * Output final state
382 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000383 PUT_UINT32_BE( ctx->state[0], output, 0 );
384 PUT_UINT32_BE( ctx->state[1], output, 4 );
385 PUT_UINT32_BE( ctx->state[2], output, 8 );
386 PUT_UINT32_BE( ctx->state[3], output, 12 );
387 PUT_UINT32_BE( ctx->state[4], output, 16 );
388 PUT_UINT32_BE( ctx->state[5], output, 20 );
389 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
391 if( ctx->is224 == 0 )
Paul Bakker5c2364c2012-10-01 14:41:15 +0000392 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100393
394 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000395}
396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200398
Paul Bakker5121ce52009-01-03 21:22:43 +0000399/*
400 * output = SHA-256( input buffer )
401 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100402int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100403 size_t ilen,
Gilles Peskined7b3d922021-05-13 00:45:25 +0200404 unsigned char *output,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100405 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000406{
Janos Follath24eed8d2019-11-22 13:21:35 +0000407 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
Hanno Becker8d215e72018-12-18 17:53:21 +0000410 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
411 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
412 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000413
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100415
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100416 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100417 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100418
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100419 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100420 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100421
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100422 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100423 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100424
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100425exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100427
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100428 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429}
430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000432/*
433 * FIPS-180-2 test vectors
434 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000435static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000436{
437 { "abc" },
438 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
439 { "" }
440};
441
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100442static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000443{
444 3, 56, 1000
445};
446
Paul Bakker9e36f042013-06-30 14:34:05 +0200447static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000448{
449 /*
450 * SHA-224 test vectors
451 */
452 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
453 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
454 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
455 0xE3, 0x6C, 0x9D, 0xA7 },
456 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
457 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
458 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
459 0x52, 0x52, 0x25, 0x25 },
460 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
461 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
462 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
463 0x4E, 0xE7, 0xAD, 0x67 },
464
465 /*
466 * SHA-256 test vectors
467 */
468 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
469 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
470 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
471 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
472 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
473 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
474 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
475 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
476 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
477 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
478 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
479 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
480};
481
482/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000483 * Checkup routine
484 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000486{
Paul Bakker5b4af392014-06-26 12:09:34 +0200487 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500488 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200489 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Russ Butlerbb83b422016-10-12 17:36:50 -0500492 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
493 if( NULL == buf )
494 {
495 if( verbose != 0 )
496 mbedtls_printf( "Buffer allocation failed\n" );
497
498 return( 1 );
499 }
500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200502
Paul Bakker5121ce52009-01-03 21:22:43 +0000503 for( i = 0; i < 6; i++ )
504 {
505 j = i % 3;
506 k = i < 3;
507
508 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100511 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100512 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000513
514 if( j == 2 )
515 {
516 memset( buf, 'a', buflen = 1000 );
517
518 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100519 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100520 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100521 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100522 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100523 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100524
Paul Bakker5121ce52009-01-03 21:22:43 +0000525 }
526 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100527 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100528 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100529 sha256_test_buflen[j] );
530 if( ret != 0 )
531 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100532 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100534 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100535 goto fail;
536
Paul Bakker5121ce52009-01-03 21:22:43 +0000537
Paul Bakker9e36f042013-06-30 14:34:05 +0200538 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100539 {
540 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100541 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100542 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
544 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 }
547
548 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100551 goto exit;
552
553fail:
554 if( verbose != 0 )
555 mbedtls_printf( "failed\n" );
556
Paul Bakker5b4af392014-06-26 12:09:34 +0200557exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500559 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200560
561 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000562}
563
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566#endif /* MBEDTLS_SHA256_C */