blob: fb03cd1dccd692ba97d894beaf754db71c66b46a [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"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Rich Evans00ab4702015-02-06 13:43:58 +000037#include <string.h>
38
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_SELF_TEST)
40#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010042#else
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050044#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050046#define mbedtls_calloc calloc
47#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#endif /* MBEDTLS_PLATFORM_C */
49#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010050
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020051#if !defined(MBEDTLS_SHA256_ALT)
52
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
Paul Bakker5121ce52009-01-03 21:22:43 +000058/*
59 * 32-bit integer manipulation macros (big endian)
60 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000061#ifndef GET_UINT32_BE
62#define GET_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020063do { \
Paul Bakker5c2364c2012-10-01 14:41:15 +000064 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
65 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
66 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
67 | ( (uint32_t) (b)[(i) + 3] ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020068} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000069#endif
70
Paul Bakker5c2364c2012-10-01 14:41:15 +000071#ifndef PUT_UINT32_BE
72#define PUT_UINT32_BE(n,b,i) \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020073do { \
Paul Bakker5121ce52009-01-03 21:22:43 +000074 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
75 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
76 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
77 (b)[(i) + 3] = (unsigned char) ( (n) ); \
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +020078} while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +000079#endif
80
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020082{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020084}
85
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020086void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020087{
88 if( ctx == NULL )
89 return;
90
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020091 mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020092}
93
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020094void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
95 const mbedtls_sha256_context *src )
96{
97 *dst = *src;
98}
99
Paul Bakker5121ce52009-01-03 21:22:43 +0000100/*
101 * SHA-256 context setup
102 */
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100103int mbedtls_sha256_starts_ext( mbedtls_sha256_context *ctx, int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
105 ctx->total[0] = 0;
106 ctx->total[1] = 0;
107
108 if( is224 == 0 )
109 {
110 /* SHA-256 */
111 ctx->state[0] = 0x6A09E667;
112 ctx->state[1] = 0xBB67AE85;
113 ctx->state[2] = 0x3C6EF372;
114 ctx->state[3] = 0xA54FF53A;
115 ctx->state[4] = 0x510E527F;
116 ctx->state[5] = 0x9B05688C;
117 ctx->state[6] = 0x1F83D9AB;
118 ctx->state[7] = 0x5BE0CD19;
119 }
120 else
121 {
122 /* SHA-224 */
123 ctx->state[0] = 0xC1059ED8;
124 ctx->state[1] = 0x367CD507;
125 ctx->state[2] = 0x3070DD17;
126 ctx->state[3] = 0xF70E5939;
127 ctx->state[4] = 0xFFC00B31;
128 ctx->state[5] = 0x68581511;
129 ctx->state[6] = 0x64F98FA7;
130 ctx->state[7] = 0xBEFA4FA4;
131 }
132
133 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100134
135 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000136}
137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200139static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000140{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200141 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
142 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
143 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
144 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
145 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
146 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
147 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
148 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
149 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
150 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
151 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
152 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
153 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
154 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
155 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
156 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
157};
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
159#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
160#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
161
162#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
163#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
164
165#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
166#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
167
168#define F0(x,y,z) ((x & y) | (z & (x | y)))
169#define F1(x,y,z) (z ^ (x & (y ^ z)))
170
171#define R(t) \
172( \
173 W[t] = S1(W[t - 2]) + W[t - 7] + \
174 S0(W[t - 15]) + W[t - 16] \
175)
176
177#define P(a,b,c,d,e,f,g,h,x,K) \
178{ \
179 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
180 temp2 = S2(a) + F0(a,b,c); \
181 d += temp1; h = temp1 + temp2; \
182}
183
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100184int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100185 const unsigned char data[64] )
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200186{
187 uint32_t temp1, temp2, W[64];
188 uint32_t A[8];
189 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000190
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200191 for( i = 0; i < 8; i++ )
192 A[i] = ctx->state[i];
193
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200194#if defined(MBEDTLS_SHA256_SMALLER)
195 for( i = 0; i < 64; i++ )
196 {
197 if( i < 16 )
198 GET_UINT32_BE( W[i], data, 4 * i );
199 else
200 R( i );
201
202 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
203
204 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
205 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
206 }
207#else /* MBEDTLS_SHA256_SMALLER */
208 for( i = 0; i < 16; i++ )
209 GET_UINT32_BE( W[i], data, 4 * i );
210
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200211 for( i = 0; i < 16; i += 8 )
212 {
213 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
214 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
215 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
216 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
217 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
218 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
219 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
220 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
221 }
222
223 for( i = 16; i < 64; i += 8 )
224 {
225 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
226 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
227 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
228 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
229 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
230 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
231 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
232 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
233 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200234#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200235
236 for( i = 0; i < 8; i++ )
237 ctx->state[i] += A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100238
239 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000240}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
243/*
244 * SHA-256 process buffer
245 */
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100246int mbedtls_sha256_update_ext( mbedtls_sha256_context *ctx,
247 const unsigned char *input,
248 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000249{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100250 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000251 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000252 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
Brian White12895d12014-04-11 11:29:42 -0400254 if( ilen == 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100255 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
257 left = ctx->total[0] & 0x3F;
258 fill = 64 - left;
259
Paul Bakker5c2364c2012-10-01 14:41:15 +0000260 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000261 ctx->total[0] &= 0xFFFFFFFF;
262
Paul Bakker5c2364c2012-10-01 14:41:15 +0000263 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000264 ctx->total[1]++;
265
266 if( left && ilen >= fill )
267 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200268 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100269
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100270 if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100271 return( ret );
272
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 input += fill;
274 ilen -= fill;
275 left = 0;
276 }
277
278 while( ilen >= 64 )
279 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100280 if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100281 return( ret );
282
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 input += 64;
284 ilen -= 64;
285 }
286
287 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200288 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100289
290 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000291}
292
Paul Bakker9e36f042013-06-30 14:34:05 +0200293static const unsigned char sha256_padding[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000294{
295 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
296 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
297 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
299};
300
301/*
302 * SHA-256 final digest
303 */
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100304int mbedtls_sha256_finish_ext( mbedtls_sha256_context *ctx,
305 unsigned char output[32] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000306{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100307 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000308 uint32_t last, padn;
309 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 unsigned char msglen[8];
311
312 high = ( ctx->total[0] >> 29 )
313 | ( ctx->total[1] << 3 );
314 low = ( ctx->total[0] << 3 );
315
Paul Bakker5c2364c2012-10-01 14:41:15 +0000316 PUT_UINT32_BE( high, msglen, 0 );
317 PUT_UINT32_BE( low, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
319 last = ctx->total[0] & 0x3F;
320 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
321
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100322 if( ( ret = mbedtls_sha256_update_ext( ctx, sha256_padding, padn ) ) != 0 )
323 return( ret );
324
325 if( ( ret = mbedtls_sha256_update_ext( ctx, msglen, 8 ) ) != 0 )
326 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000327
Paul Bakker5c2364c2012-10-01 14:41:15 +0000328 PUT_UINT32_BE( ctx->state[0], output, 0 );
329 PUT_UINT32_BE( ctx->state[1], output, 4 );
330 PUT_UINT32_BE( ctx->state[2], output, 8 );
331 PUT_UINT32_BE( ctx->state[3], output, 12 );
332 PUT_UINT32_BE( ctx->state[4], output, 16 );
333 PUT_UINT32_BE( ctx->state[5], output, 20 );
334 PUT_UINT32_BE( ctx->state[6], output, 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
336 if( ctx->is224 == 0 )
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337 PUT_UINT32_BE( ctx->state[7], output, 28 );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100338
339 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000340}
341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200343
Paul Bakker5121ce52009-01-03 21:22:43 +0000344/*
345 * output = SHA-256( input buffer )
346 */
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100347int mbedtls_sha256_ext( const unsigned char *input,
348 size_t ilen,
349 unsigned char output[32],
350 int is224 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000351{
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100352 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 mbedtls_sha256_init( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100356
357 if( ( ret = mbedtls_sha256_starts_ext( &ctx, is224 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100358 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100359
360 if( ( ret = mbedtls_sha256_update_ext( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100361 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100362
363 if( ( ret = mbedtls_sha256_finish_ext( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100364 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100365
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100366exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367 mbedtls_sha256_free( &ctx );
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100368
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100369 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000370}
371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000373/*
374 * FIPS-180-2 test vectors
375 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000376static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000377{
378 { "abc" },
379 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
380 { "" }
381};
382
Paul Bakker9e36f042013-06-30 14:34:05 +0200383static const int sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000384{
385 3, 56, 1000
386};
387
Paul Bakker9e36f042013-06-30 14:34:05 +0200388static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000389{
390 /*
391 * SHA-224 test vectors
392 */
393 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
394 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
395 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
396 0xE3, 0x6C, 0x9D, 0xA7 },
397 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
398 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
399 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
400 0x52, 0x52, 0x25, 0x25 },
401 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
402 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
403 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
404 0x4E, 0xE7, 0xAD, 0x67 },
405
406 /*
407 * SHA-256 test vectors
408 */
409 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
410 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
411 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
412 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
413 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
414 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
415 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
416 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
417 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
418 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
419 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
420 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
421};
422
423/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 * Checkup routine
425 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426int mbedtls_sha256_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000427{
Paul Bakker5b4af392014-06-26 12:09:34 +0200428 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500429 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200430 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Russ Butlerbb83b422016-10-12 17:36:50 -0500433 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
434 if( NULL == buf )
435 {
436 if( verbose != 0 )
437 mbedtls_printf( "Buffer allocation failed\n" );
438
439 return( 1 );
440 }
441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 mbedtls_sha256_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200443
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 for( i = 0; i < 6; i++ )
445 {
446 j = i % 3;
447 k = i < 3;
448
449 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100452 if( ( ret = mbedtls_sha256_starts_ext( &ctx, k ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100453 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
455 if( j == 2 )
456 {
457 memset( buf, 'a', buflen = 1000 );
458
459 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100460 {
461 ret = mbedtls_sha256_update_ext( &ctx, buf, buflen );
462 if( ret != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100463 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100464 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100465
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 }
467 else
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100468 {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100469 ret = mbedtls_sha256_update_ext( &ctx, sha256_test_buf[j],
470 sha256_test_buflen[j] );
471 if( ret != 0 )
472 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100473 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100475 if( ( ret = mbedtls_sha256_finish_ext( &ctx, sha256sum ) ) != 0 )
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100476 goto fail;
477
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
Paul Bakker9e36f042013-06-30 14:34:05 +0200479 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100480 {
481 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100482 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100483 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
485 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000487 }
488
489 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100492 goto exit;
493
494fail:
495 if( verbose != 0 )
496 mbedtls_printf( "failed\n" );
497
Paul Bakker5b4af392014-06-26 12:09:34 +0200498exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 mbedtls_sha256_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500500 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200501
502 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000503}
504
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507#endif /* MBEDTLS_SHA256_C */