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