blob: 4e0b1f32808c3228834ba3ba3b83b6a7a060be12 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
24 *
25 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/sha256.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_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +000041#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000042#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST)
45#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047#else
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Paul Bakker34617722014-06-13 17:20:13 +020053/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020055 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
56}
57
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#if !defined(MBEDTLS_SHA256_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020059
Paul Bakker5121ce52009-01-03 21:22:43 +000060/*
61 * 32-bit integer manipulation macros (big endian)
62 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000063#ifndef GET_UINT32_BE
64#define GET_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020065do { \
Paul Bakker5c2364c2012-10-01 14:41:15 +000066 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
67 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
68 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
69 | ( (uint32_t) (b)[(i) + 3] ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020070} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000071#endif
72
Paul Bakker5c2364c2012-10-01 14:41:15 +000073#ifndef PUT_UINT32_BE
74#define PUT_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020075do { \
Paul Bakker5121ce52009-01-03 21:22:43 +000076 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
77 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
78 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
79 (b)[(i) + 3] = (unsigned char) ( (n) ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020080} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000081#endif
82
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020084{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020085 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020086}
87
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020089{
90 if( ctx == NULL )
91 return;
92
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093 mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020094}
95
Paul Bakker5121ce52009-01-03 21:22:43 +000096/*
97 * SHA-256 context setup
98 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099void mbedtls_sha256_starts( 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;
130}
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200133static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000134{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200135 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
136 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
137 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
138 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
139 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
140 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
141 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
142 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
143 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
144 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
145 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
146 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
147 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
148 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
149 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
150 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
151};
Paul Bakker5121ce52009-01-03 21:22:43 +0000152
153#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
154#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
155
156#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
157#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
158
159#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
160#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
161
162#define F0(x,y,z) ((x & y) | (z & (x | y)))
163#define F1(x,y,z) (z ^ (x & (y ^ z)))
164
165#define R(t) \
166( \
167 W[t] = S1(W[t - 2]) + W[t - 7] + \
168 S0(W[t - 15]) + W[t - 16] \
169)
170
171#define P(a,b,c,d,e,f,g,h,x,K) \
172{ \
173 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
174 temp2 = S2(a) + F0(a,b,c); \
175 d += temp1; h = temp1 + temp2; \
176}
177
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200178void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
179{
180 uint32_t temp1, temp2, W[64];
181 uint32_t A[8];
182 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000183
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200184 for( i = 0; i < 8; i++ )
185 A[i] = ctx->state[i];
186
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200187#if defined(MBEDTLS_SHA256_SMALLER)
188 for( i = 0; i < 64; i++ )
189 {
190 if( i < 16 )
191 GET_UINT32_BE( W[i], data, 4 * i );
192 else
193 R( i );
194
195 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
196
197 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
198 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
199 }
200#else /* MBEDTLS_SHA256_SMALLER */
201 for( i = 0; i < 16; i++ )
202 GET_UINT32_BE( W[i], data, 4 * i );
203
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200204 for( i = 0; i < 16; i += 8 )
205 {
206 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
207 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
208 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
209 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
210 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
211 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
212 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
213 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
214 }
215
216 for( i = 16; i < 64; i += 8 )
217 {
218 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
219 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
220 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
221 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
222 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
223 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
224 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
225 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
226 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200227#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200228
229 for( i = 0; i < 8; i++ )
230 ctx->state[i] += A[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000231}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
234/*
235 * SHA-256 process buffer
236 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200238 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000239{
Paul Bakker23986e52011-04-24 08:57:21 +0000240 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000241 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
Brian White12895d12014-04-11 11:29:42 -0400243 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000244 return;
245
246 left = ctx->total[0] & 0x3F;
247 fill = 64 - left;
248
Paul Bakker5c2364c2012-10-01 14:41:15 +0000249 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000250 ctx->total[0] &= 0xFFFFFFFF;
251
Paul Bakker5c2364c2012-10-01 14:41:15 +0000252 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 ctx->total[1]++;
254
255 if( left && ilen >= fill )
256 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200257 memcpy( (void *) (ctx->buffer + left), input, fill );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258 mbedtls_sha256_process( ctx, ctx->buffer );
Paul Bakker5121ce52009-01-03 21:22:43 +0000259 input += fill;
260 ilen -= fill;
261 left = 0;
262 }
263
264 while( ilen >= 64 )
265 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266 mbedtls_sha256_process( ctx, input );
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 input += 64;
268 ilen -= 64;
269 }
270
271 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200272 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000273}
274
Paul Bakker9e36f042013-06-30 14:34:05 +0200275static const unsigned char sha256_padding[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000276{
277 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
281};
282
283/*
284 * SHA-256 final digest
285 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000287{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000288 uint32_t last, padn;
289 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 unsigned char msglen[8];
291
292 high = ( ctx->total[0] >> 29 )
293 | ( ctx->total[1] << 3 );
294 low = ( ctx->total[0] << 3 );
295
Paul Bakker5c2364c2012-10-01 14:41:15 +0000296 PUT_UINT32_BE( high, msglen, 0 );
297 PUT_UINT32_BE( low, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
299 last = ctx->total[0] & 0x3F;
300 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302 mbedtls_sha256_update( ctx, sha256_padding, padn );
303 mbedtls_sha256_update( ctx, msglen, 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
Paul Bakker5c2364c2012-10-01 14:41:15 +0000305 PUT_UINT32_BE( ctx->state[0], output, 0 );
306 PUT_UINT32_BE( ctx->state[1], output, 4 );
307 PUT_UINT32_BE( ctx->state[2], output, 8 );
308 PUT_UINT32_BE( ctx->state[3], output, 12 );
309 PUT_UINT32_BE( ctx->state[4], output, 16 );
310 PUT_UINT32_BE( ctx->state[5], output, 20 );
311 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000312
313 if( ctx->is224 == 0 )
Paul Bakker5c2364c2012-10-01 14:41:15 +0000314 PUT_UINT32_BE( ctx->state[7], output, 28 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000315}
316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319/*
320 * output = SHA-256( input buffer )
321 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322void mbedtls_sha256( const unsigned char *input, size_t ilen,
Paul Bakker9e36f042013-06-30 14:34:05 +0200323 unsigned char output[32], int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000324{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327 mbedtls_sha256_init( &ctx );
328 mbedtls_sha256_starts( &ctx, is224 );
329 mbedtls_sha256_update( &ctx, input, ilen );
330 mbedtls_sha256_finish( &ctx, output );
331 mbedtls_sha256_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000332}
333
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334#if defined(MBEDTLS_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000335/*
336 * output = SHA-256( file contents )
337 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338int mbedtls_sha256_file( const char *path, unsigned char output[32], int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000339{
340 FILE *f;
341 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000343 unsigned char buf[1024];
344
345 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 return( MBEDTLS_ERR_SHA256_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 mbedtls_sha256_init( &ctx );
349 mbedtls_sha256_starts( &ctx, is224 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352 mbedtls_sha256_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354 mbedtls_sha256_finish( &ctx, output );
355 mbedtls_sha256_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357 if( ferror( f ) != 0 )
358 {
359 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 return( MBEDTLS_ERR_SHA256_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000361 }
362
363 fclose( f );
364 return( 0 );
365}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366#endif /* MBEDTLS_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000367
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000369/*
370 * FIPS-180-2 test vectors
371 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000372static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000373{
374 { "abc" },
375 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
376 { "" }
377};
378
Paul Bakker9e36f042013-06-30 14:34:05 +0200379static const int sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000380{
381 3, 56, 1000
382};
383
Paul Bakker9e36f042013-06-30 14:34:05 +0200384static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000385{
386 /*
387 * SHA-224 test vectors
388 */
389 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
390 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
391 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
392 0xE3, 0x6C, 0x9D, 0xA7 },
393 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
394 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
395 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
396 0x52, 0x52, 0x25, 0x25 },
397 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
398 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
399 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
400 0x4E, 0xE7, 0xAD, 0x67 },
401
402 /*
403 * SHA-256 test vectors
404 */
405 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
406 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
407 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
408 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
409 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
410 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
411 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
412 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
413 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
414 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
415 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
416 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
417};
418
419/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 * Checkup routine
421 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000423{
Paul Bakker5b4af392014-06-26 12:09:34 +0200424 int i, j, k, buflen, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 unsigned char buf[1024];
Paul Bakker9e36f042013-06-30 14:34:05 +0200426 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200430
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 for( i = 0; i < 6; i++ )
432 {
433 j = i % 3;
434 k = i < 3;
435
436 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 mbedtls_sha256_starts( &ctx, k );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
441 if( j == 2 )
442 {
443 memset( buf, 'a', buflen = 1000 );
444
445 for( j = 0; j < 1000; j++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_sha256_update( &ctx, buf, buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000447 }
448 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Paul Bakker9e36f042013-06-30 14:34:05 +0200450 sha256_test_buflen[j] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 mbedtls_sha256_finish( &ctx, sha256sum );
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
Paul Bakker9e36f042013-06-30 14:34:05 +0200454 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 {
456 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
Paul Bakker5b4af392014-06-26 12:09:34 +0200459 ret = 1;
460 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000461 }
462
463 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000465 }
466
467 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Paul Bakker5b4af392014-06-26 12:09:34 +0200470exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 mbedtls_sha256_free( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200472
473 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000474}
475
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478#endif /* MBEDTLS_SHA256_C */