blob: 5c12638fdd1e5cac8e3c4b109ccbbb19440cf385 [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) \
Paul Bakker5121ce52009-01-03 21:22:43 +000065{ \
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] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000070}
71#endif
72
Paul Bakker5c2364c2012-10-01 14:41:15 +000073#ifndef PUT_UINT32_BE
74#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000075{ \
76 (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) ); \
80}
81#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)
133void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000134{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000135 uint32_t temp1, temp2, W[64];
136 uint32_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000137
Paul Bakker5c2364c2012-10-01 14:41:15 +0000138 GET_UINT32_BE( W[ 0], data, 0 );
139 GET_UINT32_BE( W[ 1], data, 4 );
140 GET_UINT32_BE( W[ 2], data, 8 );
141 GET_UINT32_BE( W[ 3], data, 12 );
142 GET_UINT32_BE( W[ 4], data, 16 );
143 GET_UINT32_BE( W[ 5], data, 20 );
144 GET_UINT32_BE( W[ 6], data, 24 );
145 GET_UINT32_BE( W[ 7], data, 28 );
146 GET_UINT32_BE( W[ 8], data, 32 );
147 GET_UINT32_BE( W[ 9], data, 36 );
148 GET_UINT32_BE( W[10], data, 40 );
149 GET_UINT32_BE( W[11], data, 44 );
150 GET_UINT32_BE( W[12], data, 48 );
151 GET_UINT32_BE( W[13], data, 52 );
152 GET_UINT32_BE( W[14], data, 56 );
153 GET_UINT32_BE( W[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000154
155#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
156#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
157
158#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
159#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
160
161#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
162#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
163
164#define F0(x,y,z) ((x & y) | (z & (x | y)))
165#define F1(x,y,z) (z ^ (x & (y ^ z)))
166
167#define R(t) \
168( \
169 W[t] = S1(W[t - 2]) + W[t - 7] + \
170 S0(W[t - 15]) + W[t - 16] \
171)
172
173#define P(a,b,c,d,e,f,g,h,x,K) \
174{ \
175 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
176 temp2 = S2(a) + F0(a,b,c); \
177 d += temp1; h = temp1 + temp2; \
178}
179
180 A = ctx->state[0];
181 B = ctx->state[1];
182 C = ctx->state[2];
183 D = ctx->state[3];
184 E = ctx->state[4];
185 F = ctx->state[5];
186 G = ctx->state[6];
187 H = ctx->state[7];
188
189 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
190 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
191 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
192 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
193 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
194 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
195 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
196 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
197 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
198 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
199 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
200 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
201 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
202 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
203 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
204 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
205 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
206 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
207 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
208 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
209 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
210 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
211 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
212 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
213 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
214 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
215 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
216 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
217 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
218 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
219 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
220 P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
221 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
222 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
223 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
224 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
225 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
226 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
227 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
228 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
229 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
230 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
231 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
232 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
233 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
234 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
235 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
236 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
237 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
238 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
239 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
240 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
241 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
242 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
243 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
244 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
245 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
246 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
247 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
248 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
249 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
250 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
251 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
252 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
253
254 ctx->state[0] += A;
255 ctx->state[1] += B;
256 ctx->state[2] += C;
257 ctx->state[3] += D;
258 ctx->state[4] += E;
259 ctx->state[5] += F;
260 ctx->state[6] += G;
261 ctx->state[7] += H;
262}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200263#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
265/*
266 * SHA-256 process buffer
267 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200269 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000270{
Paul Bakker23986e52011-04-24 08:57:21 +0000271 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000272 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
Brian White12895d12014-04-11 11:29:42 -0400274 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000275 return;
276
277 left = ctx->total[0] & 0x3F;
278 fill = 64 - left;
279
Paul Bakker5c2364c2012-10-01 14:41:15 +0000280 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000281 ctx->total[0] &= 0xFFFFFFFF;
282
Paul Bakker5c2364c2012-10-01 14:41:15 +0000283 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 ctx->total[1]++;
285
286 if( left && ilen >= fill )
287 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200288 memcpy( (void *) (ctx->buffer + left), input, fill );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 mbedtls_sha256_process( ctx, ctx->buffer );
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 input += fill;
291 ilen -= fill;
292 left = 0;
293 }
294
295 while( ilen >= 64 )
296 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297 mbedtls_sha256_process( ctx, input );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 input += 64;
299 ilen -= 64;
300 }
301
302 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200303 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304}
305
Paul Bakker9e36f042013-06-30 14:34:05 +0200306static const unsigned char sha256_padding[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000307{
308 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
312};
313
314/*
315 * SHA-256 final digest
316 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000318{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000319 uint32_t last, padn;
320 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000321 unsigned char msglen[8];
322
323 high = ( ctx->total[0] >> 29 )
324 | ( ctx->total[1] << 3 );
325 low = ( ctx->total[0] << 3 );
326
Paul Bakker5c2364c2012-10-01 14:41:15 +0000327 PUT_UINT32_BE( high, msglen, 0 );
328 PUT_UINT32_BE( low, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330 last = ctx->total[0] & 0x3F;
331 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_sha256_update( ctx, sha256_padding, padn );
334 mbedtls_sha256_update( ctx, msglen, 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
Paul Bakker5c2364c2012-10-01 14:41:15 +0000336 PUT_UINT32_BE( ctx->state[0], output, 0 );
337 PUT_UINT32_BE( ctx->state[1], output, 4 );
338 PUT_UINT32_BE( ctx->state[2], output, 8 );
339 PUT_UINT32_BE( ctx->state[3], output, 12 );
340 PUT_UINT32_BE( ctx->state[4], output, 16 );
341 PUT_UINT32_BE( ctx->state[5], output, 20 );
342 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344 if( ctx->is224 == 0 )
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345 PUT_UINT32_BE( ctx->state[7], output, 28 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000346}
347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200349
Paul Bakker5121ce52009-01-03 21:22:43 +0000350/*
351 * output = SHA-256( input buffer )
352 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353void mbedtls_sha256( const unsigned char *input, size_t ilen,
Paul Bakker9e36f042013-06-30 14:34:05 +0200354 unsigned char output[32], int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000355{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358 mbedtls_sha256_init( &ctx );
359 mbedtls_sha256_starts( &ctx, is224 );
360 mbedtls_sha256_update( &ctx, input, ilen );
361 mbedtls_sha256_finish( &ctx, output );
362 mbedtls_sha256_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000363}
364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365#if defined(MBEDTLS_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000366/*
367 * output = SHA-256( file contents )
368 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369int mbedtls_sha256_file( const char *path, unsigned char output[32], int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000370{
371 FILE *f;
372 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000374 unsigned char buf[1024];
375
376 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 return( MBEDTLS_ERR_SHA256_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 mbedtls_sha256_init( &ctx );
380 mbedtls_sha256_starts( &ctx, is224 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
382 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_sha256_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 mbedtls_sha256_finish( &ctx, output );
386 mbedtls_sha256_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
388 if( ferror( f ) != 0 )
389 {
390 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 return( MBEDTLS_ERR_SHA256_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000392 }
393
394 fclose( f );
395 return( 0 );
396}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397#endif /* MBEDTLS_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000400/*
401 * FIPS-180-2 test vectors
402 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000403static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000404{
405 { "abc" },
406 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
407 { "" }
408};
409
Paul Bakker9e36f042013-06-30 14:34:05 +0200410static const int sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000411{
412 3, 56, 1000
413};
414
Paul Bakker9e36f042013-06-30 14:34:05 +0200415static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000416{
417 /*
418 * SHA-224 test vectors
419 */
420 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
421 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
422 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
423 0xE3, 0x6C, 0x9D, 0xA7 },
424 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
425 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
426 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
427 0x52, 0x52, 0x25, 0x25 },
428 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
429 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
430 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
431 0x4E, 0xE7, 0xAD, 0x67 },
432
433 /*
434 * SHA-256 test vectors
435 */
436 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
437 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
438 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
439 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
440 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
441 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
442 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
443 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
444 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
445 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
446 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
447 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
448};
449
450/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000451 * Checkup routine
452 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000454{
Paul Bakker5b4af392014-06-26 12:09:34 +0200455 int i, j, k, buflen, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 unsigned char buf[1024];
Paul Bakker9e36f042013-06-30 14:34:05 +0200457 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200461
Paul Bakker5121ce52009-01-03 21:22:43 +0000462 for( i = 0; i < 6; i++ )
463 {
464 j = i % 3;
465 k = i < 3;
466
467 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 mbedtls_sha256_starts( &ctx, k );
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
472 if( j == 2 )
473 {
474 memset( buf, 'a', buflen = 1000 );
475
476 for( j = 0; j < 1000; j++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 mbedtls_sha256_update( &ctx, buf, buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000478 }
479 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480 mbedtls_sha256_update( &ctx, sha256_test_buf[j],
Paul Bakker9e36f042013-06-30 14:34:05 +0200481 sha256_test_buflen[j] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483 mbedtls_sha256_finish( &ctx, sha256sum );
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
Paul Bakker9e36f042013-06-30 14:34:05 +0200485 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000486 {
487 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
Paul Bakker5b4af392014-06-26 12:09:34 +0200490 ret = 1;
491 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000492 }
493
494 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 }
497
498 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
Paul Bakker5b4af392014-06-26 12:09:34 +0200501exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 mbedtls_sha256_free( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200503
504 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000505}
506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509#endif /* MBEDTLS_SHA256_C */