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