blob: bbb3108f7e198db5adef444dbdd37a17a9443c70 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
27 *
28 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
29 */
30
Paul Bakker40e46942009-01-03 21:51:57 +000031#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Paul Bakker40e46942009-01-03 21:51:57 +000033#if defined(POLARSSL_SHA4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker40e46942009-01-03 21:51:57 +000035#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker5121ce52009-01-03 21:22:43 +000037#include <stdio.h>
38
39/*
40 * 64-bit integer manipulation macros (big endian)
41 */
42#ifndef GET_UINT64_BE
43#define GET_UINT64_BE(n,b,i) \
44{ \
45 (n) = ( (unsigned int64) (b)[(i) ] << 56 ) \
46 | ( (unsigned int64) (b)[(i) + 1] << 48 ) \
47 | ( (unsigned int64) (b)[(i) + 2] << 40 ) \
48 | ( (unsigned int64) (b)[(i) + 3] << 32 ) \
49 | ( (unsigned int64) (b)[(i) + 4] << 24 ) \
50 | ( (unsigned int64) (b)[(i) + 5] << 16 ) \
51 | ( (unsigned int64) (b)[(i) + 6] << 8 ) \
52 | ( (unsigned int64) (b)[(i) + 7] ); \
53}
54#endif
55
56#ifndef PUT_UINT64_BE
57#define PUT_UINT64_BE(n,b,i) \
58{ \
59 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
60 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
61 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
62 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
63 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
64 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
65 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
66 (b)[(i) + 7] = (unsigned char) ( (n) ); \
67}
68#endif
69
70/*
71 * Round constants
72 */
73static const unsigned int64 K[80] =
74{
75 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
76 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
77 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
78 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
79 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
80 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
81 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
82 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
83 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
84 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
85 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
86 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
87 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
88 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
89 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
90 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
91 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
92 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
93 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
94 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
95 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
96 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
97 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
98 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
99 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
100 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
101 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
102 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
103 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
104 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
105 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
106 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
107 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
108 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
109 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
110 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
111 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
112 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
113 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
114 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
115};
116
117/*
118 * SHA-512 context setup
119 */
120void sha4_starts( sha4_context *ctx, int is384 )
121{
122 ctx->total[0] = 0;
123 ctx->total[1] = 0;
124
125 if( is384 == 0 )
126 {
127 /* SHA-512 */
128 ctx->state[0] = UL64(0x6A09E667F3BCC908);
129 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
130 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
131 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
132 ctx->state[4] = UL64(0x510E527FADE682D1);
133 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
134 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
135 ctx->state[7] = UL64(0x5BE0CD19137E2179);
136 }
137 else
138 {
139 /* SHA-384 */
140 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
141 ctx->state[1] = UL64(0x629A292A367CD507);
142 ctx->state[2] = UL64(0x9159015A3070DD17);
143 ctx->state[3] = UL64(0x152FECD8F70E5939);
144 ctx->state[4] = UL64(0x67332667FFC00B31);
145 ctx->state[5] = UL64(0x8EB44A8768581511);
146 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
147 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
148 }
149
150 ctx->is384 = is384;
151}
152
Paul Bakkerff60ee62010-03-16 21:09:09 +0000153static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000154{
155 int i;
156 unsigned int64 temp1, temp2, W[80];
157 unsigned int64 A, B, C, D, E, F, G, H;
158
159#define SHR(x,n) (x >> n)
160#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
161
162#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
163#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
164
165#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
166#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
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 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
178 for( i = 0; i < 16; i++ )
179 {
180 GET_UINT64_BE( W[i], data, i << 3 );
181 }
182
183 for( ; i < 80; i++ )
184 {
185 W[i] = S1(W[i - 2]) + W[i - 7] +
186 S0(W[i - 15]) + W[i - 16];
187 }
188
189 A = ctx->state[0];
190 B = ctx->state[1];
191 C = ctx->state[2];
192 D = ctx->state[3];
193 E = ctx->state[4];
194 F = ctx->state[5];
195 G = ctx->state[6];
196 H = ctx->state[7];
197 i = 0;
198
199 do
200 {
201 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
202 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
203 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
204 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
205 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
206 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
207 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
208 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
209 }
210 while( i < 80 );
211
212 ctx->state[0] += A;
213 ctx->state[1] += B;
214 ctx->state[2] += C;
215 ctx->state[3] += D;
216 ctx->state[4] += E;
217 ctx->state[5] += F;
218 ctx->state[6] += G;
219 ctx->state[7] += H;
220}
221
222/*
223 * SHA-512 process buffer
224 */
Paul Bakker23986e52011-04-24 08:57:21 +0000225void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000226{
Paul Bakker23986e52011-04-24 08:57:21 +0000227 size_t fill;
Paul Bakker5121ce52009-01-03 21:22:43 +0000228 unsigned int64 left;
229
230 if( ilen <= 0 )
231 return;
232
233 left = ctx->total[0] & 0x7F;
234 fill = (int)( 128 - left );
235
Paul Bakker23986e52011-04-24 08:57:21 +0000236 ctx->total[0] += (unsigned int64) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000237
238 if( ctx->total[0] < (unsigned int64) ilen )
239 ctx->total[1]++;
240
241 if( left && ilen >= fill )
242 {
243 memcpy( (void *) (ctx->buffer + left),
244 (void *) input, fill );
245 sha4_process( ctx, ctx->buffer );
246 input += fill;
247 ilen -= fill;
248 left = 0;
249 }
250
251 while( ilen >= 128 )
252 {
253 sha4_process( ctx, input );
254 input += 128;
255 ilen -= 128;
256 }
257
258 if( ilen > 0 )
259 {
260 memcpy( (void *) (ctx->buffer + left),
261 (void *) input, ilen );
262 }
263}
264
265static const unsigned char sha4_padding[128] =
266{
267 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
269 0, 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};
276
277/*
278 * SHA-512 final digest
279 */
280void sha4_finish( sha4_context *ctx, unsigned char output[64] )
281{
282 int last, padn;
283 unsigned int64 high, low;
284 unsigned char msglen[16];
285
286 high = ( ctx->total[0] >> 61 )
287 | ( ctx->total[1] << 3 );
288 low = ( ctx->total[0] << 3 );
289
290 PUT_UINT64_BE( high, msglen, 0 );
291 PUT_UINT64_BE( low, msglen, 8 );
292
293 last = (int)( ctx->total[0] & 0x7F );
294 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
295
296 sha4_update( ctx, (unsigned char *) sha4_padding, padn );
297 sha4_update( ctx, msglen, 16 );
298
299 PUT_UINT64_BE( ctx->state[0], output, 0 );
300 PUT_UINT64_BE( ctx->state[1], output, 8 );
301 PUT_UINT64_BE( ctx->state[2], output, 16 );
302 PUT_UINT64_BE( ctx->state[3], output, 24 );
303 PUT_UINT64_BE( ctx->state[4], output, 32 );
304 PUT_UINT64_BE( ctx->state[5], output, 40 );
305
306 if( ctx->is384 == 0 )
307 {
308 PUT_UINT64_BE( ctx->state[6], output, 48 );
309 PUT_UINT64_BE( ctx->state[7], output, 56 );
310 }
311}
312
313/*
314 * output = SHA-512( input buffer )
315 */
Paul Bakker23986e52011-04-24 08:57:21 +0000316void sha4( const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000317 unsigned char output[64], int is384 )
318{
319 sha4_context ctx;
320
321 sha4_starts( &ctx, is384 );
322 sha4_update( &ctx, input, ilen );
323 sha4_finish( &ctx, output );
324
325 memset( &ctx, 0, sizeof( sha4_context ) );
326}
327
328/*
329 * output = SHA-512( file contents )
330 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000331int sha4_file( const char *path, unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000332{
333 FILE *f;
334 size_t n;
335 sha4_context ctx;
336 unsigned char buf[1024];
337
338 if( ( f = fopen( path, "rb" ) ) == NULL )
339 return( 1 );
340
341 sha4_starts( &ctx, is384 );
342
343 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
344 sha4_update( &ctx, buf, (int) n );
345
346 sha4_finish( &ctx, output );
347
348 memset( &ctx, 0, sizeof( sha4_context ) );
349
350 if( ferror( f ) != 0 )
351 {
352 fclose( f );
353 return( 2 );
354 }
355
356 fclose( f );
357 return( 0 );
358}
359
360/*
361 * SHA-512 HMAC context setup
362 */
Paul Bakker23986e52011-04-24 08:57:21 +0000363void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, size_t keylen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000364 int is384 )
365{
Paul Bakker23986e52011-04-24 08:57:21 +0000366 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000367 unsigned char sum[64];
368
369 if( keylen > 128 )
370 {
371 sha4( key, keylen, sum, is384 );
372 keylen = ( is384 ) ? 48 : 64;
373 key = sum;
374 }
375
376 memset( ctx->ipad, 0x36, 128 );
377 memset( ctx->opad, 0x5C, 128 );
378
379 for( i = 0; i < keylen; i++ )
380 {
381 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
382 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
383 }
384
385 sha4_starts( ctx, is384 );
386 sha4_update( ctx, ctx->ipad, 128 );
387
388 memset( sum, 0, sizeof( sum ) );
389}
390
391/*
392 * SHA-512 HMAC process buffer
393 */
394void sha4_hmac_update( sha4_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000395 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000396{
397 sha4_update( ctx, input, ilen );
398}
399
400/*
401 * SHA-512 HMAC final digest
402 */
403void sha4_hmac_finish( sha4_context *ctx, unsigned char output[64] )
404{
405 int is384, hlen;
406 unsigned char tmpbuf[64];
407
408 is384 = ctx->is384;
409 hlen = ( is384 == 0 ) ? 64 : 48;
410
411 sha4_finish( ctx, tmpbuf );
412 sha4_starts( ctx, is384 );
413 sha4_update( ctx, ctx->opad, 128 );
414 sha4_update( ctx, tmpbuf, hlen );
415 sha4_finish( ctx, output );
416
417 memset( tmpbuf, 0, sizeof( tmpbuf ) );
418}
419
420/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000421 * SHA-512 HMAC context reset
422 */
423void sha4_hmac_reset( sha4_context *ctx )
424{
425 sha4_starts( ctx, ctx->is384 );
426 sha4_update( ctx, ctx->ipad, 128 );
427}
428
429/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 * output = HMAC-SHA-512( hmac key, input buffer )
431 */
Paul Bakker23986e52011-04-24 08:57:21 +0000432void sha4_hmac( const unsigned char *key, size_t keylen,
433 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 unsigned char output[64], int is384 )
435{
436 sha4_context ctx;
437
438 sha4_hmac_starts( &ctx, key, keylen, is384 );
439 sha4_hmac_update( &ctx, input, ilen );
440 sha4_hmac_finish( &ctx, output );
441
442 memset( &ctx, 0, sizeof( sha4_context ) );
443}
444
Paul Bakker40e46942009-01-03 21:51:57 +0000445#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
447/*
448 * FIPS-180-2 test vectors
449 */
450static unsigned char sha4_test_buf[3][113] =
451{
452 { "abc" },
453 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
454 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
455 { "" }
456};
457
458static const int sha4_test_buflen[3] =
459{
460 3, 112, 1000
461};
462
463static const unsigned char sha4_test_sum[6][64] =
464{
465 /*
466 * SHA-384 test vectors
467 */
468 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
469 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
470 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
471 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
472 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
473 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
474 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
475 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
476 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
477 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
478 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
479 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
480 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
481 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
482 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
483 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
484 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
485 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
486
487 /*
488 * SHA-512 test vectors
489 */
490 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
491 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
492 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
493 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
494 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
495 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
496 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
497 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
498 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
499 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
500 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
501 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
502 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
503 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
504 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
505 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
506 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
507 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
508 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
509 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
510 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
511 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
512 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
513 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
514};
515
516/*
517 * RFC 4231 test vectors
518 */
519static unsigned char sha4_hmac_test_key[7][26] =
520{
521 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
522 "\x0B\x0B\x0B\x0B" },
523 { "Jefe" },
524 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
525 "\xAA\xAA\xAA\xAA" },
526 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
527 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
528 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
529 "\x0C\x0C\x0C\x0C" },
530 { "" }, /* 0xAA 131 times */
531 { "" }
532};
533
534static const int sha4_hmac_test_keylen[7] =
535{
536 20, 4, 20, 25, 20, 131, 131
537};
538
539static unsigned char sha4_hmac_test_buf[7][153] =
540{
541 { "Hi There" },
542 { "what do ya want for nothing?" },
543 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
544 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
545 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
546 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
547 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
548 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
549 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
550 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
551 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
552 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
553 { "Test With Truncation" },
554 { "Test Using Larger Than Block-Size Key - Hash Key First" },
555 { "This is a test using a larger than block-size key "
556 "and a larger than block-size data. The key needs to "
557 "be hashed before being used by the HMAC algorithm." }
558};
559
560static const int sha4_hmac_test_buflen[7] =
561{
562 8, 28, 50, 50, 20, 54, 152
563};
564
565static const unsigned char sha4_hmac_test_sum[14][64] =
566{
567 /*
568 * HMAC-SHA-384 test vectors
569 */
570 { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
571 0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
572 0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
573 0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
574 0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
575 0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
576 { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
577 0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
578 0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
579 0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
580 0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
581 0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
582 { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
583 0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
584 0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
585 0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
586 0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
587 0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
588 { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
589 0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
590 0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
591 0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
592 0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
593 0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
594 { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
595 0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
596 { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
597 0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
598 0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
599 0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
600 0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
601 0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
602 { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
603 0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
604 0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
605 0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
606 0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
607 0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
608
609 /*
610 * HMAC-SHA-512 test vectors
611 */
612 { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
613 0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
614 0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
615 0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
616 0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
617 0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
618 0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
619 0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
620 { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
621 0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
622 0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
623 0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
624 0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
625 0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
626 0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
627 0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
628 { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
629 0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
630 0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
631 0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
632 0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
633 0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
634 0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
635 0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
636 { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
637 0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
638 0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
639 0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
640 0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
641 0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
642 0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
643 0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
644 { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
645 0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
646 { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
647 0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
648 0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
649 0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
650 0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
651 0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
652 0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
653 0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
654 { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
655 0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
656 0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
657 0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
658 0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
659 0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
660 0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
661 0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
662};
663
664/*
665 * Checkup routine
666 */
667int sha4_self_test( int verbose )
668{
669 int i, j, k, buflen;
670 unsigned char buf[1024];
671 unsigned char sha4sum[64];
672 sha4_context ctx;
673
674 for( i = 0; i < 6; i++ )
675 {
676 j = i % 3;
677 k = i < 3;
678
679 if( verbose != 0 )
680 printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
681
682 sha4_starts( &ctx, k );
683
684 if( j == 2 )
685 {
686 memset( buf, 'a', buflen = 1000 );
687
688 for( j = 0; j < 1000; j++ )
689 sha4_update( &ctx, buf, buflen );
690 }
691 else
692 sha4_update( &ctx, sha4_test_buf[j],
693 sha4_test_buflen[j] );
694
695 sha4_finish( &ctx, sha4sum );
696
697 if( memcmp( sha4sum, sha4_test_sum[i], 64 - k * 16 ) != 0 )
698 {
699 if( verbose != 0 )
700 printf( "failed\n" );
701
702 return( 1 );
703 }
704
705 if( verbose != 0 )
706 printf( "passed\n" );
707 }
708
709 if( verbose != 0 )
710 printf( "\n" );
711
712 for( i = 0; i < 14; i++ )
713 {
714 j = i % 7;
715 k = i < 7;
716
717 if( verbose != 0 )
718 printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 );
719
720 if( j == 5 || j == 6 )
721 {
722 memset( buf, '\xAA', buflen = 131 );
723 sha4_hmac_starts( &ctx, buf, buflen, k );
724 }
725 else
726 sha4_hmac_starts( &ctx, sha4_hmac_test_key[j],
727 sha4_hmac_test_keylen[j], k );
728
729 sha4_hmac_update( &ctx, sha4_hmac_test_buf[j],
730 sha4_hmac_test_buflen[j] );
731
732 sha4_hmac_finish( &ctx, sha4sum );
733
734 buflen = ( j == 4 ) ? 16 : 64 - k * 16;
735
736 if( memcmp( sha4sum, sha4_hmac_test_sum[i], buflen ) != 0 )
737 {
738 if( verbose != 0 )
739 printf( "failed\n" );
740
741 return( 1 );
742 }
743
744 if( verbose != 0 )
745 printf( "passed\n" );
746 }
747
748 if( verbose != 0 )
749 printf( "\n" );
750
751 return( 0 );
752}
753
754#endif
755
756#endif