blob: dbb4a898616404308c76b496ff1a692d082754a6 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
23 *
24 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
25 */
26
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020029#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050045#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050047#define mbedtls_calloc calloc
48#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#endif /* MBEDTLS_PLATFORM_C */
50#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010051
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020052#if !defined(MBEDTLS_SHA256_ALT)
53
Paul Bakker5121ce52009-01-03 21:22:43 +000054/*
55 * 32-bit integer manipulation macros (big endian)
56 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000057#ifndef GET_UINT32_BE
58#define GET_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020059do { \
Paul Bakker5c2364c2012-10-01 14:41:15 +000060 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
61 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
62 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
63 | ( (uint32_t) (b)[(i) + 3] ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020064} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000065#endif
66
Paul Bakker5c2364c2012-10-01 14:41:15 +000067#ifndef PUT_UINT32_BE
68#define PUT_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020069do { \
Paul Bakker5121ce52009-01-03 21:22:43 +000070 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
71 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
72 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
73 (b)[(i) + 3] = (unsigned char) ( (n) ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020074} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000075#endif
76
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020078{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020080}
81
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020083{
84 if( ctx == NULL )
85 return;
86
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050087 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020088}
89
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020090void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
91 const mbedtls_sha256_context *src )
92{
93 *dst = *src;
94}
95
Paul Bakker5121ce52009-01-03 21:22:43 +000096/*
97 * SHA-256 context setup
98 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010099int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000100{
101 ctx->total[0] = 0;
102 ctx->total[1] = 0;
103
104 if( is224 == 0 )
105 {
106 /* SHA-256 */
107 ctx->state[0] = 0x6A09E667;
108 ctx->state[1] = 0xBB67AE85;
109 ctx->state[2] = 0x3C6EF372;
110 ctx->state[3] = 0xA54FF53A;
111 ctx->state[4] = 0x510E527F;
112 ctx->state[5] = 0x9B05688C;
113 ctx->state[6] = 0x1F83D9AB;
114 ctx->state[7] = 0x5BE0CD19;
115 }
116 else
117 {
118 /* SHA-224 */
119 ctx->state[0] = 0xC1059ED8;
120 ctx->state[1] = 0x367CD507;
121 ctx->state[2] = 0x3070DD17;
122 ctx->state[3] = 0xF70E5939;
123 ctx->state[4] = 0xFFC00B31;
124 ctx->state[5] = 0x68581511;
125 ctx->state[6] = 0x64F98FA7;
126 ctx->state[7] = 0xBEFA4FA4;
127 }
128
129 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100130
131 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000132}
133
Jaeden Amero041039f2018-02-19 15:28:08 +0000134#if !defined(MBEDTLS_DEPRECATED_REMOVED)
135void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
136 int is224 )
137{
138 mbedtls_sha256_starts_ret( ctx, is224 );
139}
140#endif
141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200143static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000144{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200145 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
146 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
147 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
148 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
149 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
150 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
151 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
152 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
153 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
154 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
155 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
156 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
157 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
158 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
159 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
160 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
161};
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
163#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
164#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
165
166#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
167#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
168
169#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
170#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
171
172#define F0(x,y,z) ((x & y) | (z & (x | y)))
173#define F1(x,y,z) (z ^ (x & (y ^ z)))
174
175#define R(t) \
176( \
177 W[t] = S1(W[t - 2]) + W[t - 7] + \
178 S0(W[t - 15]) + W[t - 16] \
179)
180
181#define P(a,b,c,d,e,f,g,h,x,K) \
182{ \
183 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
184 temp2 = S2(a) + F0(a,b,c); \
185 d += temp1; h = temp1 + temp2; \
186}
187
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{
191 uint32_t temp1, temp2, W[64];
192 uint32_t A[8];
193 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +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 )
202 GET_UINT32_BE( W[i], data, 4 * i );
203 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++ )
213 GET_UINT32_BE( W[i], data, 4 * i );
214
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
Brian White12895d12014-04-11 11:29:42 -0400266 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100267 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
269 left = ctx->total[0] & 0x3F;
270 fill = 64 - left;
271
Paul Bakker5c2364c2012-10-01 14:41:15 +0000272 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 ctx->total[0] &= 0xFFFFFFFF;
274
Paul Bakker5c2364c2012-10-01 14:41:15 +0000275 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000276 ctx->total[1]++;
277
278 if( left && ilen >= fill )
279 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200280 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100281
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100282 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100283 return( ret );
284
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 input += fill;
286 ilen -= fill;
287 left = 0;
288 }
289
290 while( ilen >= 64 )
291 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100292 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100293 return( ret );
294
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 input += 64;
296 ilen -= 64;
297 }
298
299 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200300 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100301
302 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303}
304
Jaeden Amero041039f2018-02-19 15:28:08 +0000305#if !defined(MBEDTLS_DEPRECATED_REMOVED)
306void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
307 const unsigned char *input,
308 size_t ilen )
309{
310 mbedtls_sha256_update_ret( ctx, input, ilen );
311}
312#endif
313
Paul Bakker5121ce52009-01-03 21:22:43 +0000314/*
315 * SHA-256 final digest
316 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100317int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100318 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000319{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100320 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200321 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000322 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200324 /*
325 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
326 */
327 used = ctx->total[0] & 0x3F;
328
329 ctx->buffer[used++] = 0x80;
330
331 if( used <= 56 )
332 {
333 /* Enough room for padding + length in current block */
334 memset( ctx->buffer + used, 0, 56 - used );
335 }
336 else
337 {
338 /* We'll need an extra block */
339 memset( ctx->buffer + used, 0, 64 - used );
340
341 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
342 return( ret );
343
344 memset( ctx->buffer, 0, 56 );
345 }
346
347 /*
348 * Add message length
349 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000350 high = ( ctx->total[0] >> 29 )
351 | ( ctx->total[1] << 3 );
352 low = ( ctx->total[0] << 3 );
353
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200354 PUT_UINT32_BE( high, ctx->buffer, 56 );
355 PUT_UINT32_BE( low, ctx->buffer, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200357 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100358 return( ret );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100359
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200360 /*
361 * Output final state
362 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000363 PUT_UINT32_BE( ctx->state[0], output, 0 );
364 PUT_UINT32_BE( ctx->state[1], output, 4 );
365 PUT_UINT32_BE( ctx->state[2], output, 8 );
366 PUT_UINT32_BE( ctx->state[3], output, 12 );
367 PUT_UINT32_BE( ctx->state[4], output, 16 );
368 PUT_UINT32_BE( ctx->state[5], output, 20 );
369 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
371 if( ctx->is224 == 0 )
Paul Bakker5c2364c2012-10-01 14:41:15 +0000372 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100373
374 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000375}
376
Jaeden Amero041039f2018-02-19 15:28:08 +0000377#if !defined(MBEDTLS_DEPRECATED_REMOVED)
378void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
379 unsigned char output[32] )
380{
381 mbedtls_sha256_finish_ret( ctx, output );
382}
383#endif
384
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200386
Paul Bakker5121ce52009-01-03 21:22:43 +0000387/*
388 * output = SHA-256( input buffer )
389 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100390int mbedtls_sha256_ret( const unsigned char *input,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100391 size_t ilen,
392 unsigned char output[32],
393 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000394{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100395 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100399
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100400 if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100401 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100402
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100403 if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100404 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100405
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100406 if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100407 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100408
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100409exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200410 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100411
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100412 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000413}
414
Jaeden Amero041039f2018-02-19 15:28:08 +0000415#if !defined(MBEDTLS_DEPRECATED_REMOVED)
416void mbedtls_sha256( const unsigned char *input,
417 size_t ilen,
418 unsigned char output[32],
419 int is224 )
420{
421 mbedtls_sha256_ret( input, ilen, output, is224 );
422}
423#endif
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000426/*
427 * FIPS-180-2 test vectors
428 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000429static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000430{
431 { "abc" },
432 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
433 { "" }
434};
435
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100436static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000437{
438 3, 56, 1000
439};
440
Paul Bakker9e36f042013-06-30 14:34:05 +0200441static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000442{
443 /*
444 * SHA-224 test vectors
445 */
446 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
447 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
448 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
449 0xE3, 0x6C, 0x9D, 0xA7 },
450 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
451 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
452 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
453 0x52, 0x52, 0x25, 0x25 },
454 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
455 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
456 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
457 0x4E, 0xE7, 0xAD, 0x67 },
458
459 /*
460 * SHA-256 test vectors
461 */
462 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
463 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
464 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
465 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
466 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
467 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
468 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
469 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
470 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
471 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
472 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
473 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
474};
475
476/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000477 * Checkup routine
478 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000480{
Paul Bakker5b4af392014-06-26 12:09:34 +0200481 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500482 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200483 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
Russ Butlerbb83b422016-10-12 17:36:50 -0500486 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
487 if( NULL == buf )
488 {
489 if( verbose != 0 )
490 mbedtls_printf( "Buffer allocation failed\n" );
491
492 return( 1 );
493 }
494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200496
Paul Bakker5121ce52009-01-03 21:22:43 +0000497 for( i = 0; i < 6; i++ )
498 {
499 j = i % 3;
500 k = i < 3;
501
502 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100505 if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100506 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000507
508 if( j == 2 )
509 {
510 memset( buf, 'a', buflen = 1000 );
511
512 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100513 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100514 ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100515 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100516 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100517 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100518
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 }
520 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100521 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100522 ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100523 sha256_test_buflen[j] );
524 if( ret != 0 )
525 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100526 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100528 if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100529 goto fail;
530
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
Paul Bakker9e36f042013-06-30 14:34:05 +0200532 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100533 {
534 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100535 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100536 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000537
538 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000540 }
541
542 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000544
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100545 goto exit;
546
547fail:
548 if( verbose != 0 )
549 mbedtls_printf( "failed\n" );
550
Paul Bakker5b4af392014-06-26 12:09:34 +0200551exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500553 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200554
555 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000556}
557
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000559
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560#endif /* MBEDTLS_SHA256_C */