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