blob: ebdc997340878494b0938ea673dc0d4c03814cf6 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Paul Bakker530927b2015-02-13 14:24:10 +01004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnarde12abf92015-01-28 17:13:45 +00006 * This file is part of mbed TLS (https://polarssl.org)
Paul Bakkere0ccd0a2009-01-04 16:27:10 +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-512 Secure Hash Standard was published by NIST in 2002.
24 *
25 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
26 */
27
Paul Bakker40e46942009-01-03 21:51:57 +000028#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Paul Bakker40e46942009-01-03 21:51:57 +000030#if defined(POLARSSL_SHA4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Paul Bakker40e46942009-01-03 21:51:57 +000032#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Paul Bakker335db3f2011-04-25 15:28:35 +000034#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000035#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000036#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Manuel Pégourié-Gonnardaa4e55b2015-08-31 11:22:01 +020038#if !defined(POLARSSL_SHA4_ALT)
39
Paul Bakker312da332014-06-13 17:20:13 +020040/* Implementation that should never be optimized out by the compiler */
41static void polarssl_zeroize( void *v, size_t n ) {
42 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
43}
44
Paul Bakker5121ce52009-01-03 21:22:43 +000045/*
46 * 64-bit integer manipulation macros (big endian)
47 */
48#ifndef GET_UINT64_BE
49#define GET_UINT64_BE(n,b,i) \
50{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000051 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
52 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
53 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
54 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
55 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
56 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
57 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
58 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000059}
60#endif
61
62#ifndef PUT_UINT64_BE
63#define PUT_UINT64_BE(n,b,i) \
64{ \
65 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
66 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
67 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
68 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
69 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
70 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
71 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
72 (b)[(i) + 7] = (unsigned char) ( (n) ); \
73}
74#endif
75
76/*
77 * Round constants
78 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000079static const uint64_t K[80] =
Paul Bakker5121ce52009-01-03 21:22:43 +000080{
81 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
82 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
83 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
84 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
85 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
86 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
87 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
88 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
89 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
90 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
91 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
92 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
93 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
94 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
95 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
96 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
97 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
98 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
99 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
100 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
101 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
102 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
103 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
104 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
105 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
106 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
107 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
108 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
109 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
110 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
111 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
112 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
113 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
114 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
115 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
116 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
117 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
118 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
119 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
120 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
121};
122
123/*
124 * SHA-512 context setup
125 */
126void sha4_starts( sha4_context *ctx, int is384 )
127{
128 ctx->total[0] = 0;
129 ctx->total[1] = 0;
130
131 if( is384 == 0 )
132 {
133 /* SHA-512 */
134 ctx->state[0] = UL64(0x6A09E667F3BCC908);
135 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
136 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
137 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
138 ctx->state[4] = UL64(0x510E527FADE682D1);
139 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
140 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
141 ctx->state[7] = UL64(0x5BE0CD19137E2179);
142 }
143 else
144 {
145 /* SHA-384 */
146 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
147 ctx->state[1] = UL64(0x629A292A367CD507);
148 ctx->state[2] = UL64(0x9159015A3070DD17);
149 ctx->state[3] = UL64(0x152FECD8F70E5939);
150 ctx->state[4] = UL64(0x67332667FFC00B31);
151 ctx->state[5] = UL64(0x8EB44A8768581511);
152 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
153 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
154 }
155
156 ctx->is384 = is384;
157}
158
Paul Bakkerff60ee62010-03-16 21:09:09 +0000159static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000160{
161 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000162 uint64_t temp1, temp2, W[80];
163 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
165#define SHR(x,n) (x >> n)
166#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
167
168#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
169#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
170
171#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
172#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
173
174#define F0(x,y,z) ((x & y) | (z & (x | y)))
175#define F1(x,y,z) (z ^ (x & (y ^ z)))
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
184 for( i = 0; i < 16; i++ )
185 {
186 GET_UINT64_BE( W[i], data, i << 3 );
187 }
188
189 for( ; i < 80; i++ )
190 {
191 W[i] = S1(W[i - 2]) + W[i - 7] +
192 S0(W[i - 15]) + W[i - 16];
193 }
194
195 A = ctx->state[0];
196 B = ctx->state[1];
197 C = ctx->state[2];
198 D = ctx->state[3];
199 E = ctx->state[4];
200 F = ctx->state[5];
201 G = ctx->state[6];
202 H = ctx->state[7];
203 i = 0;
204
205 do
206 {
207 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
208 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
209 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
210 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
211 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
212 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
213 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
214 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
215 }
216 while( i < 80 );
217
218 ctx->state[0] += A;
219 ctx->state[1] += B;
220 ctx->state[2] += C;
221 ctx->state[3] += D;
222 ctx->state[4] += E;
223 ctx->state[5] += F;
224 ctx->state[6] += G;
225 ctx->state[7] += H;
226}
227
228/*
229 * SHA-512 process buffer
230 */
Paul Bakker23986e52011-04-24 08:57:21 +0000231void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000232{
Paul Bakker23986e52011-04-24 08:57:21 +0000233 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000234 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000235
236 if( ilen <= 0 )
237 return;
238
Paul Bakkerb8213a12011-07-11 08:16:18 +0000239 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000240 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000241
Paul Bakker5c2364c2012-10-01 14:41:15 +0000242 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
Paul Bakker5c2364c2012-10-01 14:41:15 +0000244 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000245 ctx->total[1]++;
246
247 if( left && ilen >= fill )
248 {
Paul Bakkereae09db2013-06-06 12:35:54 +0200249 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000250 sha4_process( ctx, ctx->buffer );
251 input += fill;
252 ilen -= fill;
253 left = 0;
254 }
255
256 while( ilen >= 128 )
257 {
258 sha4_process( ctx, input );
259 input += 128;
260 ilen -= 128;
261 }
262
263 if( ilen > 0 )
Paul Bakkereae09db2013-06-06 12:35:54 +0200264 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000265}
266
267static const unsigned char sha4_padding[128] =
268{
269 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
275 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
277};
278
279/*
280 * SHA-512 final digest
281 */
282void sha4_finish( sha4_context *ctx, unsigned char output[64] )
283{
Paul Bakker27fdf462011-06-09 13:55:13 +0000284 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000285 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000286 unsigned char msglen[16];
287
288 high = ( ctx->total[0] >> 61 )
289 | ( ctx->total[1] << 3 );
290 low = ( ctx->total[0] << 3 );
291
292 PUT_UINT64_BE( high, msglen, 0 );
293 PUT_UINT64_BE( low, msglen, 8 );
294
Paul Bakker27fdf462011-06-09 13:55:13 +0000295 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000296 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
297
Paul Bakkereae09db2013-06-06 12:35:54 +0200298 sha4_update( ctx, sha4_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 sha4_update( ctx, msglen, 16 );
300
301 PUT_UINT64_BE( ctx->state[0], output, 0 );
302 PUT_UINT64_BE( ctx->state[1], output, 8 );
303 PUT_UINT64_BE( ctx->state[2], output, 16 );
304 PUT_UINT64_BE( ctx->state[3], output, 24 );
305 PUT_UINT64_BE( ctx->state[4], output, 32 );
306 PUT_UINT64_BE( ctx->state[5], output, 40 );
307
308 if( ctx->is384 == 0 )
309 {
310 PUT_UINT64_BE( ctx->state[6], output, 48 );
311 PUT_UINT64_BE( ctx->state[7], output, 56 );
312 }
313}
314
Paul Bakker4087c472013-06-12 16:49:10 +0200315#endif /* !POLARSSL_SHA4_ALT */
316
Paul Bakker5121ce52009-01-03 21:22:43 +0000317/*
318 * output = SHA-512( input buffer )
319 */
Paul Bakker23986e52011-04-24 08:57:21 +0000320void sha4( const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000321 unsigned char output[64], int is384 )
322{
323 sha4_context ctx;
324
325 sha4_starts( &ctx, is384 );
326 sha4_update( &ctx, input, ilen );
327 sha4_finish( &ctx, output );
328
Paul Bakker312da332014-06-13 17:20:13 +0200329 polarssl_zeroize( &ctx, sizeof( sha4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000330}
331
Paul Bakker335db3f2011-04-25 15:28:35 +0000332#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000333/*
334 * output = SHA-512( file contents )
335 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000336int sha4_file( const char *path, unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000337{
338 FILE *f;
339 size_t n;
340 sha4_context ctx;
341 unsigned char buf[1024];
342
343 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000344 return( POLARSSL_ERR_SHA4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346 sha4_starts( &ctx, is384 );
347
348 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000349 sha4_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351 sha4_finish( &ctx, output );
352
Paul Bakker312da332014-06-13 17:20:13 +0200353 polarssl_zeroize( &ctx, sizeof( sha4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
355 if( ferror( f ) != 0 )
356 {
357 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000358 return( POLARSSL_ERR_SHA4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000359 }
360
361 fclose( f );
362 return( 0 );
363}
Paul Bakker335db3f2011-04-25 15:28:35 +0000364#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
366/*
367 * SHA-512 HMAC context setup
368 */
Paul Bakker23986e52011-04-24 08:57:21 +0000369void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, size_t keylen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000370 int is384 )
371{
Paul Bakker23986e52011-04-24 08:57:21 +0000372 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000373 unsigned char sum[64];
374
375 if( keylen > 128 )
376 {
377 sha4( key, keylen, sum, is384 );
378 keylen = ( is384 ) ? 48 : 64;
379 key = sum;
380 }
381
382 memset( ctx->ipad, 0x36, 128 );
383 memset( ctx->opad, 0x5C, 128 );
384
385 for( i = 0; i < keylen; i++ )
386 {
387 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
388 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
389 }
390
391 sha4_starts( ctx, is384 );
392 sha4_update( ctx, ctx->ipad, 128 );
393
Paul Bakker312da332014-06-13 17:20:13 +0200394 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000395}
396
397/*
398 * SHA-512 HMAC process buffer
399 */
400void sha4_hmac_update( sha4_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000401 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000402{
403 sha4_update( ctx, input, ilen );
404}
405
406/*
407 * SHA-512 HMAC final digest
408 */
409void sha4_hmac_finish( sha4_context *ctx, unsigned char output[64] )
410{
411 int is384, hlen;
412 unsigned char tmpbuf[64];
413
414 is384 = ctx->is384;
415 hlen = ( is384 == 0 ) ? 64 : 48;
416
417 sha4_finish( ctx, tmpbuf );
418 sha4_starts( ctx, is384 );
419 sha4_update( ctx, ctx->opad, 128 );
420 sha4_update( ctx, tmpbuf, hlen );
421 sha4_finish( ctx, output );
422
Paul Bakker312da332014-06-13 17:20:13 +0200423 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424}
425
426/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000427 * SHA-512 HMAC context reset
428 */
429void sha4_hmac_reset( sha4_context *ctx )
430{
431 sha4_starts( ctx, ctx->is384 );
432 sha4_update( ctx, ctx->ipad, 128 );
433}
434
435/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 * output = HMAC-SHA-512( hmac key, input buffer )
437 */
Paul Bakker23986e52011-04-24 08:57:21 +0000438void sha4_hmac( const unsigned char *key, size_t keylen,
439 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 unsigned char output[64], int is384 )
441{
442 sha4_context ctx;
443
444 sha4_hmac_starts( &ctx, key, keylen, is384 );
445 sha4_hmac_update( &ctx, input, ilen );
446 sha4_hmac_finish( &ctx, output );
447
Paul Bakker312da332014-06-13 17:20:13 +0200448 polarssl_zeroize( &ctx, sizeof( sha4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449}
450
Paul Bakker40e46942009-01-03 21:51:57 +0000451#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453/*
454 * FIPS-180-2 test vectors
455 */
456static unsigned char sha4_test_buf[3][113] =
457{
458 { "abc" },
459 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
460 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
461 { "" }
462};
463
464static const int sha4_test_buflen[3] =
465{
466 3, 112, 1000
467};
468
469static const unsigned char sha4_test_sum[6][64] =
470{
471 /*
472 * SHA-384 test vectors
473 */
474 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
475 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
476 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
477 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
478 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
479 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
480 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
481 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
482 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
483 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
484 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
485 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
486 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
487 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
488 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
489 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
490 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
491 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
492
493 /*
494 * SHA-512 test vectors
495 */
496 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
497 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
498 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
499 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
500 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
501 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
502 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
503 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
504 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
505 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
506 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
507 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
508 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
509 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
510 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
511 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
512 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
513 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
514 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
515 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
516 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
517 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
518 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
519 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
520};
521
522/*
523 * RFC 4231 test vectors
524 */
525static unsigned char sha4_hmac_test_key[7][26] =
526{
527 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
528 "\x0B\x0B\x0B\x0B" },
529 { "Jefe" },
530 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
531 "\xAA\xAA\xAA\xAA" },
532 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
533 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
534 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
535 "\x0C\x0C\x0C\x0C" },
536 { "" }, /* 0xAA 131 times */
537 { "" }
538};
539
540static const int sha4_hmac_test_keylen[7] =
541{
542 20, 4, 20, 25, 20, 131, 131
543};
544
545static unsigned char sha4_hmac_test_buf[7][153] =
546{
547 { "Hi There" },
548 { "what do ya want for nothing?" },
549 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
550 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
551 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
552 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
553 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
554 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
555 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
556 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
557 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
558 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
559 { "Test With Truncation" },
560 { "Test Using Larger Than Block-Size Key - Hash Key First" },
561 { "This is a test using a larger than block-size key "
562 "and a larger than block-size data. The key needs to "
563 "be hashed before being used by the HMAC algorithm." }
564};
565
566static const int sha4_hmac_test_buflen[7] =
567{
568 8, 28, 50, 50, 20, 54, 152
569};
570
571static const unsigned char sha4_hmac_test_sum[14][64] =
572{
573 /*
574 * HMAC-SHA-384 test vectors
575 */
576 { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
577 0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
578 0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
579 0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
580 0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
581 0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
582 { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
583 0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
584 0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
585 0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
586 0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
587 0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
588 { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
589 0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
590 0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
591 0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
592 0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
593 0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
594 { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
595 0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
596 0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
597 0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
598 0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
599 0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
600 { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
601 0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
602 { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
603 0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
604 0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
605 0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
606 0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
607 0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
608 { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
609 0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
610 0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
611 0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
612 0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
613 0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
614
615 /*
616 * HMAC-SHA-512 test vectors
617 */
618 { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
619 0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
620 0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
621 0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
622 0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
623 0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
624 0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
625 0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
626 { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
627 0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
628 0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
629 0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
630 0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
631 0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
632 0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
633 0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
634 { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
635 0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
636 0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
637 0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
638 0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
639 0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
640 0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
641 0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
642 { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
643 0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
644 0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
645 0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
646 0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
647 0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
648 0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
649 0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
650 { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
651 0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
652 { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
653 0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
654 0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
655 0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
656 0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
657 0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
658 0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
659 0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
660 { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
661 0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
662 0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
663 0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
664 0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
665 0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
666 0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
667 0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
668};
669
670/*
671 * Checkup routine
672 */
673int sha4_self_test( int verbose )
674{
675 int i, j, k, buflen;
676 unsigned char buf[1024];
677 unsigned char sha4sum[64];
678 sha4_context ctx;
679
680 for( i = 0; i < 6; i++ )
681 {
682 j = i % 3;
683 k = i < 3;
684
685 if( verbose != 0 )
686 printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
687
688 sha4_starts( &ctx, k );
689
690 if( j == 2 )
691 {
692 memset( buf, 'a', buflen = 1000 );
693
694 for( j = 0; j < 1000; j++ )
695 sha4_update( &ctx, buf, buflen );
696 }
697 else
698 sha4_update( &ctx, sha4_test_buf[j],
699 sha4_test_buflen[j] );
700
701 sha4_finish( &ctx, sha4sum );
702
703 if( memcmp( sha4sum, sha4_test_sum[i], 64 - k * 16 ) != 0 )
704 {
705 if( verbose != 0 )
706 printf( "failed\n" );
707
708 return( 1 );
709 }
710
711 if( verbose != 0 )
712 printf( "passed\n" );
713 }
714
715 if( verbose != 0 )
716 printf( "\n" );
717
718 for( i = 0; i < 14; i++ )
719 {
720 j = i % 7;
721 k = i < 7;
722
723 if( verbose != 0 )
724 printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 );
725
726 if( j == 5 || j == 6 )
727 {
728 memset( buf, '\xAA', buflen = 131 );
729 sha4_hmac_starts( &ctx, buf, buflen, k );
730 }
731 else
732 sha4_hmac_starts( &ctx, sha4_hmac_test_key[j],
733 sha4_hmac_test_keylen[j], k );
734
735 sha4_hmac_update( &ctx, sha4_hmac_test_buf[j],
736 sha4_hmac_test_buflen[j] );
737
738 sha4_hmac_finish( &ctx, sha4sum );
739
740 buflen = ( j == 4 ) ? 16 : 64 - k * 16;
741
742 if( memcmp( sha4sum, sha4_hmac_test_sum[i], buflen ) != 0 )
743 {
744 if( verbose != 0 )
745 printf( "failed\n" );
746
747 return( 1 );
748 }
749
750 if( verbose != 0 )
751 printf( "passed\n" );
752 }
753
754 if( verbose != 0 )
755 printf( "\n" );
756
757 return( 0 );
758}
759
760#endif
761
762#endif