blob: be373d9cb0b0efe72faa5fa1201b4306a18080e3 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
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
Jerome Forissier79013242021-07-28 10:24:04 +020025#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020026
27#if defined(MBEDTLS_SHA256_C)
28
29#include "mbedtls/sha256.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010030#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020031#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020032
33#include <string.h>
34
35#if defined(MBEDTLS_SELF_TEST)
36#if defined(MBEDTLS_PLATFORM_C)
37#include "mbedtls/platform.h"
38#else
39#include <stdio.h>
40#include <stdlib.h>
41#define mbedtls_printf printf
42#define mbedtls_calloc calloc
43#define mbedtls_free free
44#endif /* MBEDTLS_PLATFORM_C */
45#endif /* MBEDTLS_SELF_TEST */
46
Jens Wiklander3d3b0592019-03-20 15:30:29 +010047#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 )
Jens Wiklander817466c2018-05-22 13:49:31 +020050
Jens Wiklander3d3b0592019-03-20 15:30:29 +010051#if !defined(MBEDTLS_SHA256_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +020052
53/*
54 * 32-bit integer manipulation macros (big endian)
55 */
56#ifndef GET_UINT32_BE
57#define GET_UINT32_BE(n,b,i) \
58do { \
59 (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] ); \
63} while( 0 )
64#endif
65
66#ifndef PUT_UINT32_BE
67#define PUT_UINT32_BE(n,b,i) \
68do { \
69 (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) ); \
73} while( 0 )
74#endif
75
76void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
77{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010078 SHA256_VALIDATE( ctx != NULL );
79
Jens Wiklander817466c2018-05-22 13:49:31 +020080 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
81}
82
83void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
84{
85 if( ctx == NULL )
86 return;
87
Jens Wiklander3d3b0592019-03-20 15:30:29 +010088 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +020089}
90
91void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
92 const mbedtls_sha256_context *src )
93{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010094 SHA256_VALIDATE( dst != NULL );
95 SHA256_VALIDATE( src != NULL );
96
Jens Wiklander817466c2018-05-22 13:49:31 +020097 *dst = *src;
98}
99
100/*
101 * SHA-256 context setup
102 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100103int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200104{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100105 SHA256_VALIDATE_RET( ctx != NULL );
106 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
107
Jens Wiklander817466c2018-05-22 13:49:31 +0200108 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;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100137
138 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200139}
140
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100141#if !defined(MBEDTLS_DEPRECATED_REMOVED)
142void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
143 int is224 )
144{
145 mbedtls_sha256_starts_ret( ctx, is224 );
146}
147#endif
148
Jens Wiklander817466c2018-05-22 13:49:31 +0200149#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
150static const uint32_t K[] =
151{
152 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
153 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
154 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
155 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
156 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
157 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
158 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
159 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
160 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
161 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
162 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
163 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
164 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
165 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
166 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
167 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
168};
169
Jerome Forissier5b25c762020-04-07 11:18:49 +0200170#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n))
171#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200172
173#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
174#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
175
176#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
177#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
178
Jerome Forissier5b25c762020-04-07 11:18:49 +0200179#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
180#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200181
Jerome Forissier79013242021-07-28 10:24:04 +0200182#define R(t) \
183 ( \
184 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
185 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200186 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200187
Jerome Forissier79013242021-07-28 10:24:04 +0200188#define P(a,b,c,d,e,f,g,h,x,K) \
189 do \
190 { \
191 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
192 local.temp2 = S2(a) + F0((a),(b),(c)); \
193 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200194 } while( 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200195
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100196int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
197 const unsigned char data[64] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200198{
Jerome Forissier79013242021-07-28 10:24:04 +0200199 struct
200 {
201 uint32_t temp1, temp2, W[64];
202 uint32_t A[8];
203 } local;
204
Jens Wiklander817466c2018-05-22 13:49:31 +0200205 unsigned int i;
206
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100207 SHA256_VALIDATE_RET( ctx != NULL );
208 SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
209
Jens Wiklander817466c2018-05-22 13:49:31 +0200210 for( i = 0; i < 8; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +0200211 local.A[i] = ctx->state[i];
Jens Wiklander817466c2018-05-22 13:49:31 +0200212
213#if defined(MBEDTLS_SHA256_SMALLER)
214 for( i = 0; i < 64; i++ )
215 {
216 if( i < 16 )
Jerome Forissier79013242021-07-28 10:24:04 +0200217 GET_UINT32_BE( local.W[i], data, 4 * i );
Jens Wiklander817466c2018-05-22 13:49:31 +0200218 else
219 R( i );
220
Jerome Forissier79013242021-07-28 10:24:04 +0200221 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
222 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200223
Jerome Forissier79013242021-07-28 10:24:04 +0200224 local.temp1 = local.A[7]; local.A[7] = local.A[6];
225 local.A[6] = local.A[5]; local.A[5] = local.A[4];
226 local.A[4] = local.A[3]; local.A[3] = local.A[2];
227 local.A[2] = local.A[1]; local.A[1] = local.A[0];
228 local.A[0] = local.temp1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200229 }
230#else /* MBEDTLS_SHA256_SMALLER */
231 for( i = 0; i < 16; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +0200232 GET_UINT32_BE( local.W[i], data, 4 * i );
Jens Wiklander817466c2018-05-22 13:49:31 +0200233
234 for( i = 0; i < 16; i += 8 )
235 {
Jerome Forissier79013242021-07-28 10:24:04 +0200236 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
237 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
238 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
239 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
240 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
241 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
242 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
243 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
244 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
245 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
246 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
247 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
248 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
249 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
250 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
251 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200252 }
253
254 for( i = 16; i < 64; i += 8 )
255 {
Jerome Forissier79013242021-07-28 10:24:04 +0200256 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
257 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
258 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
259 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
260 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
261 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
262 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
263 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
264 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
265 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
266 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
267 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
268 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
269 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
270 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
271 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
Jens Wiklander817466c2018-05-22 13:49:31 +0200272 }
273#endif /* MBEDTLS_SHA256_SMALLER */
274
275 for( i = 0; i < 8; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +0200276 ctx->state[i] += local.A[i];
277
278 /* Zeroise buffers and variables to clear sensitive data from memory. */
279 mbedtls_platform_zeroize( &local, sizeof( local ) );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100280
281 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200282}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100283
284#if !defined(MBEDTLS_DEPRECATED_REMOVED)
285void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
286 const unsigned char data[64] )
287{
288 mbedtls_internal_sha256_process( ctx, data );
289}
290#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200291#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
292
293/*
294 * SHA-256 process buffer
295 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100296int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
297 const unsigned char *input,
298 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200299{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200300 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200301 size_t fill;
302 uint32_t left;
303
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100304 SHA256_VALIDATE_RET( ctx != NULL );
305 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
306
Jens Wiklander817466c2018-05-22 13:49:31 +0200307 if( ilen == 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100308 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200309
310 left = ctx->total[0] & 0x3F;
311 fill = 64 - left;
312
313 ctx->total[0] += (uint32_t) ilen;
314 ctx->total[0] &= 0xFFFFFFFF;
315
316 if( ctx->total[0] < (uint32_t) ilen )
317 ctx->total[1]++;
318
319 if( left && ilen >= fill )
320 {
321 memcpy( (void *) (ctx->buffer + left), input, fill );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100322
323 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
324 return( ret );
325
Jens Wiklander817466c2018-05-22 13:49:31 +0200326 input += fill;
327 ilen -= fill;
328 left = 0;
329 }
330
331 while( ilen >= 64 )
332 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100333 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
334 return( ret );
335
Jens Wiklander817466c2018-05-22 13:49:31 +0200336 input += 64;
337 ilen -= 64;
338 }
339
340 if( ilen > 0 )
341 memcpy( (void *) (ctx->buffer + left), input, ilen );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100342
343 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200344}
345
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100346#if !defined(MBEDTLS_DEPRECATED_REMOVED)
347void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
348 const unsigned char *input,
349 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200350{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100351 mbedtls_sha256_update_ret( ctx, input, ilen );
352}
353#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200354
355/*
356 * SHA-256 final digest
357 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100358int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
359 unsigned char output[32] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200360{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200361 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100362 uint32_t used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200363 uint32_t high, low;
Jens Wiklander817466c2018-05-22 13:49:31 +0200364
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100365 SHA256_VALIDATE_RET( ctx != NULL );
366 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
367
368 /*
369 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
370 */
371 used = ctx->total[0] & 0x3F;
372
373 ctx->buffer[used++] = 0x80;
374
375 if( used <= 56 )
376 {
377 /* Enough room for padding + length in current block */
378 memset( ctx->buffer + used, 0, 56 - used );
379 }
380 else
381 {
382 /* We'll need an extra block */
383 memset( ctx->buffer + used, 0, 64 - used );
384
385 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
386 return( ret );
387
388 memset( ctx->buffer, 0, 56 );
389 }
390
391 /*
392 * Add message length
393 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200394 high = ( ctx->total[0] >> 29 )
395 | ( ctx->total[1] << 3 );
396 low = ( ctx->total[0] << 3 );
397
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100398 PUT_UINT32_BE( high, ctx->buffer, 56 );
399 PUT_UINT32_BE( low, ctx->buffer, 60 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200400
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100401 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
402 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200403
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100404 /*
405 * Output final state
406 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200407 PUT_UINT32_BE( ctx->state[0], output, 0 );
408 PUT_UINT32_BE( ctx->state[1], output, 4 );
409 PUT_UINT32_BE( ctx->state[2], output, 8 );
410 PUT_UINT32_BE( ctx->state[3], output, 12 );
411 PUT_UINT32_BE( ctx->state[4], output, 16 );
412 PUT_UINT32_BE( ctx->state[5], output, 20 );
413 PUT_UINT32_BE( ctx->state[6], output, 24 );
414
415 if( ctx->is224 == 0 )
416 PUT_UINT32_BE( ctx->state[7], output, 28 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100417
418 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200419}
420
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100421#if !defined(MBEDTLS_DEPRECATED_REMOVED)
422void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
423 unsigned char output[32] )
424{
425 mbedtls_sha256_finish_ret( ctx, output );
426}
427#endif
428
Jens Wiklander817466c2018-05-22 13:49:31 +0200429#endif /* !MBEDTLS_SHA256_ALT */
430
431/*
432 * output = SHA-256( input buffer )
433 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100434int mbedtls_sha256_ret( const unsigned char *input,
435 size_t ilen,
436 unsigned char output[32],
437 int is224 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200438{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200439 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200440 mbedtls_sha256_context ctx;
441
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100442 SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
443 SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
444 SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
445
Jens Wiklander817466c2018-05-22 13:49:31 +0200446 mbedtls_sha256_init( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100447
448 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
449 goto exit;
450
451 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
452 goto exit;
453
454 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
455 goto exit;
456
457exit:
Jens Wiklander817466c2018-05-22 13:49:31 +0200458 mbedtls_sha256_free( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100459
460 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200461}
462
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100463#if !defined(MBEDTLS_DEPRECATED_REMOVED)
464void mbedtls_sha256( const unsigned char *input,
465 size_t ilen,
466 unsigned char output[32],
467 int is224 )
468{
469 mbedtls_sha256_ret( input, ilen, output, is224 );
470}
471#endif
472
Jens Wiklander817466c2018-05-22 13:49:31 +0200473#if defined(MBEDTLS_SELF_TEST)
474/*
475 * FIPS-180-2 test vectors
476 */
477static const unsigned char sha256_test_buf[3][57] =
478{
479 { "abc" },
480 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
481 { "" }
482};
483
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100484static const size_t sha256_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200485{
486 3, 56, 1000
487};
488
489static const unsigned char sha256_test_sum[6][32] =
490{
491 /*
492 * SHA-224 test vectors
493 */
494 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
495 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
496 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
497 0xE3, 0x6C, 0x9D, 0xA7 },
498 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
499 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
500 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
501 0x52, 0x52, 0x25, 0x25 },
502 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
503 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
504 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
505 0x4E, 0xE7, 0xAD, 0x67 },
506
507 /*
508 * SHA-256 test vectors
509 */
510 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
511 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
512 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
513 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
514 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
515 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
516 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
517 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
518 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
519 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
520 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
521 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
522};
523
524/*
525 * Checkup routine
526 */
527int mbedtls_sha256_self_test( int verbose )
528{
529 int i, j, k, buflen, ret = 0;
530 unsigned char *buf;
531 unsigned char sha256sum[32];
532 mbedtls_sha256_context ctx;
533
534 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
535 if( NULL == buf )
536 {
537 if( verbose != 0 )
538 mbedtls_printf( "Buffer allocation failed\n" );
539
540 return( 1 );
541 }
542
543 mbedtls_sha256_init( &ctx );
544
545 for( i = 0; i < 6; i++ )
546 {
547 j = i % 3;
548 k = i < 3;
549
550 if( verbose != 0 )
551 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
552
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100553 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
554 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200555
556 if( j == 2 )
557 {
558 memset( buf, 'a', buflen = 1000 );
559
560 for( j = 0; j < 1000; j++ )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100561 {
562 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
563 if( ret != 0 )
564 goto fail;
565 }
566
Jens Wiklander817466c2018-05-22 13:49:31 +0200567 }
568 else
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100569 {
570 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
571 sha256_test_buflen[j] );
572 if( ret != 0 )
573 goto fail;
574 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200575
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100576 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
577 goto fail;
578
Jens Wiklander817466c2018-05-22 13:49:31 +0200579
580 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
581 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200582 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100583 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200584 }
585
586 if( verbose != 0 )
587 mbedtls_printf( "passed\n" );
588 }
589
590 if( verbose != 0 )
591 mbedtls_printf( "\n" );
592
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100593 goto exit;
594
595fail:
596 if( verbose != 0 )
597 mbedtls_printf( "failed\n" );
598
Jens Wiklander817466c2018-05-22 13:49:31 +0200599exit:
600 mbedtls_sha256_free( &ctx );
601 mbedtls_free( buf );
602
603 return( ret );
604}
605
606#endif /* MBEDTLS_SELF_TEST */
607
608#endif /* MBEDTLS_SHA256_C */