blob: d04a42485089c9aef0d1ec530f0d1b4a490ce765 [file] [log] [blame]
Jaeden Ameroe54e6932018-08-06 16:19:58 +01001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * 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.
18 *
19 * This file is part of Mbed Crypto (https://tls.mbed.org)
20 */
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
27#if !defined(MBEDCRYPTO_CONFIG_FILE)
28#include "mbedcrypto/config.h"
29#else
30#include MBEDCRYPTO_CONFIG_FILE
31#endif
32
33#if defined(MBEDCRYPTO_SHA256_C)
34
35#include "mbedcrypto/sha256.h"
36#include "mbedcrypto/platform_util.h"
37
38#include <string.h>
39
40#if defined(MBEDCRYPTO_SELF_TEST)
41#if defined(MBEDCRYPTO_PLATFORM_C)
42#include "mbedcrypto/platform.h"
43#else
44#include <stdio.h>
45#include <stdlib.h>
46#define mbedcrypto_printf printf
47#define mbedcrypto_calloc calloc
48#define mbedcrypto_free free
49#endif /* MBEDCRYPTO_PLATFORM_C */
50#endif /* MBEDCRYPTO_SELF_TEST */
51
52#if !defined(MBEDCRYPTO_SHA256_ALT)
53
54/*
55 * 32-bit integer manipulation macros (big endian)
56 */
57#ifndef GET_UINT32_BE
58#define GET_UINT32_BE(n,b,i) \
59do { \
60 (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] ); \
64} while( 0 )
65#endif
66
67#ifndef PUT_UINT32_BE
68#define PUT_UINT32_BE(n,b,i) \
69do { \
70 (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) ); \
74} while( 0 )
75#endif
76
77void mbedcrypto_sha256_init( mbedcrypto_sha256_context *ctx )
78{
79 memset( ctx, 0, sizeof( mbedcrypto_sha256_context ) );
80}
81
82void mbedcrypto_sha256_free( mbedcrypto_sha256_context *ctx )
83{
84 if( ctx == NULL )
85 return;
86
87 mbedcrypto_platform_zeroize( ctx, sizeof( mbedcrypto_sha256_context ) );
88}
89
90void mbedcrypto_sha256_clone( mbedcrypto_sha256_context *dst,
91 const mbedcrypto_sha256_context *src )
92{
93 *dst = *src;
94}
95
96/*
97 * SHA-256 context setup
98 */
99int mbedcrypto_sha256_starts_ret( mbedcrypto_sha256_context *ctx, int is224 )
100{
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 return( 0 );
132}
133
134#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
135void mbedcrypto_sha256_starts( mbedcrypto_sha256_context *ctx,
136 int is224 )
137{
138 mbedcrypto_sha256_starts_ret( ctx, is224 );
139}
140#endif
141
142#if !defined(MBEDCRYPTO_SHA256_PROCESS_ALT)
143static const uint32_t K[] =
144{
145 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};
162
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
188int mbedcrypto_internal_sha256_process( mbedcrypto_sha256_context *ctx,
189 const unsigned char data[64] )
190{
191 uint32_t temp1, temp2, W[64];
192 uint32_t A[8];
193 unsigned int i;
194
195 for( i = 0; i < 8; i++ )
196 A[i] = ctx->state[i];
197
198#if defined(MBEDCRYPTO_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 /* MBEDCRYPTO_SHA256_SMALLER */
212 for( i = 0; i < 16; i++ )
213 GET_UINT32_BE( W[i], data, 4 * i );
214
215 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 }
238#endif /* MBEDCRYPTO_SHA256_SMALLER */
239
240 for( i = 0; i < 8; i++ )
241 ctx->state[i] += A[i];
242
243 return( 0 );
244}
245
246#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
247void mbedcrypto_sha256_process( mbedcrypto_sha256_context *ctx,
248 const unsigned char data[64] )
249{
250 mbedcrypto_internal_sha256_process( ctx, data );
251}
252#endif
253#endif /* !MBEDCRYPTO_SHA256_PROCESS_ALT */
254
255/*
256 * SHA-256 process buffer
257 */
258int mbedcrypto_sha256_update_ret( mbedcrypto_sha256_context *ctx,
259 const unsigned char *input,
260 size_t ilen )
261{
262 int ret;
263 size_t fill;
264 uint32_t left;
265
266 if( ilen == 0 )
267 return( 0 );
268
269 left = ctx->total[0] & 0x3F;
270 fill = 64 - left;
271
272 ctx->total[0] += (uint32_t) ilen;
273 ctx->total[0] &= 0xFFFFFFFF;
274
275 if( ctx->total[0] < (uint32_t) ilen )
276 ctx->total[1]++;
277
278 if( left && ilen >= fill )
279 {
280 memcpy( (void *) (ctx->buffer + left), input, fill );
281
282 if( ( ret = mbedcrypto_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
283 return( ret );
284
285 input += fill;
286 ilen -= fill;
287 left = 0;
288 }
289
290 while( ilen >= 64 )
291 {
292 if( ( ret = mbedcrypto_internal_sha256_process( ctx, input ) ) != 0 )
293 return( ret );
294
295 input += 64;
296 ilen -= 64;
297 }
298
299 if( ilen > 0 )
300 memcpy( (void *) (ctx->buffer + left), input, ilen );
301
302 return( 0 );
303}
304
305#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
306void mbedcrypto_sha256_update( mbedcrypto_sha256_context *ctx,
307 const unsigned char *input,
308 size_t ilen )
309{
310 mbedcrypto_sha256_update_ret( ctx, input, ilen );
311}
312#endif
313
314static const unsigned char sha256_padding[64] =
315{
316 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
320};
321
322/*
323 * SHA-256 final digest
324 */
325int mbedcrypto_sha256_finish_ret( mbedcrypto_sha256_context *ctx,
326 unsigned char output[32] )
327{
328 int ret;
329 uint32_t last, padn;
330 uint32_t high, low;
331 unsigned char msglen[8];
332
333 high = ( ctx->total[0] >> 29 )
334 | ( ctx->total[1] << 3 );
335 low = ( ctx->total[0] << 3 );
336
337 PUT_UINT32_BE( high, msglen, 0 );
338 PUT_UINT32_BE( low, msglen, 4 );
339
340 last = ctx->total[0] & 0x3F;
341 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
342
343 if( ( ret = mbedcrypto_sha256_update_ret( ctx, sha256_padding, padn ) ) != 0 )
344 return( ret );
345
346 if( ( ret = mbedcrypto_sha256_update_ret( ctx, msglen, 8 ) ) != 0 )
347 return( ret );
348
349 PUT_UINT32_BE( ctx->state[0], output, 0 );
350 PUT_UINT32_BE( ctx->state[1], output, 4 );
351 PUT_UINT32_BE( ctx->state[2], output, 8 );
352 PUT_UINT32_BE( ctx->state[3], output, 12 );
353 PUT_UINT32_BE( ctx->state[4], output, 16 );
354 PUT_UINT32_BE( ctx->state[5], output, 20 );
355 PUT_UINT32_BE( ctx->state[6], output, 24 );
356
357 if( ctx->is224 == 0 )
358 PUT_UINT32_BE( ctx->state[7], output, 28 );
359
360 return( 0 );
361}
362
363#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
364void mbedcrypto_sha256_finish( mbedcrypto_sha256_context *ctx,
365 unsigned char output[32] )
366{
367 mbedcrypto_sha256_finish_ret( ctx, output );
368}
369#endif
370
371#endif /* !MBEDCRYPTO_SHA256_ALT */
372
373/*
374 * output = SHA-256( input buffer )
375 */
376int mbedcrypto_sha256_ret( const unsigned char *input,
377 size_t ilen,
378 unsigned char output[32],
379 int is224 )
380{
381 int ret;
382 mbedcrypto_sha256_context ctx;
383
384 mbedcrypto_sha256_init( &ctx );
385
386 if( ( ret = mbedcrypto_sha256_starts_ret( &ctx, is224 ) ) != 0 )
387 goto exit;
388
389 if( ( ret = mbedcrypto_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
390 goto exit;
391
392 if( ( ret = mbedcrypto_sha256_finish_ret( &ctx, output ) ) != 0 )
393 goto exit;
394
395exit:
396 mbedcrypto_sha256_free( &ctx );
397
398 return( ret );
399}
400
401#if !defined(MBEDCRYPTO_DEPRECATED_REMOVED)
402void mbedcrypto_sha256( const unsigned char *input,
403 size_t ilen,
404 unsigned char output[32],
405 int is224 )
406{
407 mbedcrypto_sha256_ret( input, ilen, output, is224 );
408}
409#endif
410
411#if defined(MBEDCRYPTO_SELF_TEST)
412/*
413 * FIPS-180-2 test vectors
414 */
415static const unsigned char sha256_test_buf[3][57] =
416{
417 { "abc" },
418 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
419 { "" }
420};
421
422static const size_t sha256_test_buflen[3] =
423{
424 3, 56, 1000
425};
426
427static const unsigned char sha256_test_sum[6][32] =
428{
429 /*
430 * SHA-224 test vectors
431 */
432 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
433 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
434 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
435 0xE3, 0x6C, 0x9D, 0xA7 },
436 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
437 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
438 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
439 0x52, 0x52, 0x25, 0x25 },
440 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
441 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
442 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
443 0x4E, 0xE7, 0xAD, 0x67 },
444
445 /*
446 * SHA-256 test vectors
447 */
448 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
449 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
450 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
451 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
452 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
453 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
454 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
455 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
456 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
457 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
458 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
459 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
460};
461
462/*
463 * Checkup routine
464 */
465int mbedcrypto_sha256_self_test( int verbose )
466{
467 int i, j, k, buflen, ret = 0;
468 unsigned char *buf;
469 unsigned char sha256sum[32];
470 mbedcrypto_sha256_context ctx;
471
472 buf = mbedcrypto_calloc( 1024, sizeof(unsigned char) );
473 if( NULL == buf )
474 {
475 if( verbose != 0 )
476 mbedcrypto_printf( "Buffer allocation failed\n" );
477
478 return( 1 );
479 }
480
481 mbedcrypto_sha256_init( &ctx );
482
483 for( i = 0; i < 6; i++ )
484 {
485 j = i % 3;
486 k = i < 3;
487
488 if( verbose != 0 )
489 mbedcrypto_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
490
491 if( ( ret = mbedcrypto_sha256_starts_ret( &ctx, k ) ) != 0 )
492 goto fail;
493
494 if( j == 2 )
495 {
496 memset( buf, 'a', buflen = 1000 );
497
498 for( j = 0; j < 1000; j++ )
499 {
500 ret = mbedcrypto_sha256_update_ret( &ctx, buf, buflen );
501 if( ret != 0 )
502 goto fail;
503 }
504
505 }
506 else
507 {
508 ret = mbedcrypto_sha256_update_ret( &ctx, sha256_test_buf[j],
509 sha256_test_buflen[j] );
510 if( ret != 0 )
511 goto fail;
512 }
513
514 if( ( ret = mbedcrypto_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
515 goto fail;
516
517
518 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
519 {
520 ret = 1;
521 goto fail;
522 }
523
524 if( verbose != 0 )
525 mbedcrypto_printf( "passed\n" );
526 }
527
528 if( verbose != 0 )
529 mbedcrypto_printf( "\n" );
530
531 goto exit;
532
533fail:
534 if( verbose != 0 )
535 mbedcrypto_printf( "failed\n" );
536
537exit:
538 mbedcrypto_sha256_free( &ctx );
539 mbedcrypto_free( buf );
540
541 return( ret );
542}
543
544#endif /* MBEDCRYPTO_SELF_TEST */
545
546#endif /* MBEDCRYPTO_SHA256_C */