blob: 39084cb2849f3ac63bd800fa9feae73e49c5ae2c [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.
5 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakker77b385e2009-07-28 17:23:11 +00006 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
24 *
25 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
26 */
27
Paul Bakker40e46942009-01-03 21:51:57 +000028#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Paul Bakker40e46942009-01-03 21:51:57 +000030#if defined(POLARSSL_SHA4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Paul Bakker40e46942009-01-03 21:51:57 +000032#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
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
Paul Bakkerff60ee62010-03-16 21:09:09 +0000151static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000152{
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 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000223void sha4_update( sha4_context *ctx, const unsigned char *input, int ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000224{
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 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000314void sha4( const unsigned char *input, int ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000315 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 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000329int sha4_file( const char *path, unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000330{
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 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000361void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, int keylen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000362 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,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000393 const unsigned char *input, int ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000394{
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/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000419 * SHA-512 HMAC context reset
420 */
421void sha4_hmac_reset( sha4_context *ctx )
422{
423 sha4_starts( ctx, ctx->is384 );
424 sha4_update( ctx, ctx->ipad, 128 );
425}
426
427/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000428 * output = HMAC-SHA-512( hmac key, input buffer )
429 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000430void sha4_hmac( const unsigned char *key, int keylen,
431 const unsigned char *input, int ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 unsigned char output[64], int is384 )
433{
434 sha4_context ctx;
435
436 sha4_hmac_starts( &ctx, key, keylen, is384 );
437 sha4_hmac_update( &ctx, input, ilen );
438 sha4_hmac_finish( &ctx, output );
439
440 memset( &ctx, 0, sizeof( sha4_context ) );
441}
442
Paul Bakker40e46942009-01-03 21:51:57 +0000443#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
445/*
446 * FIPS-180-2 test vectors
447 */
448static unsigned char sha4_test_buf[3][113] =
449{
450 { "abc" },
451 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
452 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
453 { "" }
454};
455
456static const int sha4_test_buflen[3] =
457{
458 3, 112, 1000
459};
460
461static const unsigned char sha4_test_sum[6][64] =
462{
463 /*
464 * SHA-384 test vectors
465 */
466 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
467 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
468 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
469 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
470 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
471 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
472 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
473 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
474 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
475 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
476 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
477 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
478 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
479 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
480 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
481 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
482 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
483 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
484
485 /*
486 * SHA-512 test vectors
487 */
488 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
489 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
490 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
491 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
492 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
493 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
494 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
495 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
496 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
497 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
498 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
499 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
500 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
501 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
502 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
503 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
504 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
505 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
506 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
507 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
508 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
509 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
510 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
511 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
512};
513
514/*
515 * RFC 4231 test vectors
516 */
517static unsigned char sha4_hmac_test_key[7][26] =
518{
519 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
520 "\x0B\x0B\x0B\x0B" },
521 { "Jefe" },
522 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
523 "\xAA\xAA\xAA\xAA" },
524 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
525 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
526 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
527 "\x0C\x0C\x0C\x0C" },
528 { "" }, /* 0xAA 131 times */
529 { "" }
530};
531
532static const int sha4_hmac_test_keylen[7] =
533{
534 20, 4, 20, 25, 20, 131, 131
535};
536
537static unsigned char sha4_hmac_test_buf[7][153] =
538{
539 { "Hi There" },
540 { "what do ya want for nothing?" },
541 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
542 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
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 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
547 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
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 { "Test With Truncation" },
552 { "Test Using Larger Than Block-Size Key - Hash Key First" },
553 { "This is a test using a larger than block-size key "
554 "and a larger than block-size data. The key needs to "
555 "be hashed before being used by the HMAC algorithm." }
556};
557
558static const int sha4_hmac_test_buflen[7] =
559{
560 8, 28, 50, 50, 20, 54, 152
561};
562
563static const unsigned char sha4_hmac_test_sum[14][64] =
564{
565 /*
566 * HMAC-SHA-384 test vectors
567 */
568 { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
569 0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
570 0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
571 0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
572 0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
573 0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
574 { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
575 0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
576 0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
577 0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
578 0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
579 0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
580 { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
581 0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
582 0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
583 0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
584 0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
585 0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
586 { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
587 0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
588 0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
589 0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
590 0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
591 0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
592 { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
593 0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
594 { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
595 0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
596 0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
597 0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
598 0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
599 0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
600 { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
601 0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
602 0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
603 0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
604 0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
605 0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
606
607 /*
608 * HMAC-SHA-512 test vectors
609 */
610 { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
611 0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
612 0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
613 0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
614 0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
615 0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
616 0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
617 0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
618 { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
619 0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
620 0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
621 0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
622 0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
623 0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
624 0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
625 0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
626 { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
627 0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
628 0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
629 0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
630 0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
631 0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
632 0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
633 0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
634 { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
635 0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
636 0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
637 0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
638 0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
639 0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
640 0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
641 0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
642 { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
643 0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
644 { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
645 0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
646 0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
647 0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
648 0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
649 0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
650 0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
651 0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
652 { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
653 0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
654 0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
655 0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
656 0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
657 0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
658 0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
659 0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
660};
661
662/*
663 * Checkup routine
664 */
665int sha4_self_test( int verbose )
666{
667 int i, j, k, buflen;
668 unsigned char buf[1024];
669 unsigned char sha4sum[64];
670 sha4_context ctx;
671
672 for( i = 0; i < 6; i++ )
673 {
674 j = i % 3;
675 k = i < 3;
676
677 if( verbose != 0 )
678 printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
679
680 sha4_starts( &ctx, k );
681
682 if( j == 2 )
683 {
684 memset( buf, 'a', buflen = 1000 );
685
686 for( j = 0; j < 1000; j++ )
687 sha4_update( &ctx, buf, buflen );
688 }
689 else
690 sha4_update( &ctx, sha4_test_buf[j],
691 sha4_test_buflen[j] );
692
693 sha4_finish( &ctx, sha4sum );
694
695 if( memcmp( sha4sum, sha4_test_sum[i], 64 - k * 16 ) != 0 )
696 {
697 if( verbose != 0 )
698 printf( "failed\n" );
699
700 return( 1 );
701 }
702
703 if( verbose != 0 )
704 printf( "passed\n" );
705 }
706
707 if( verbose != 0 )
708 printf( "\n" );
709
710 for( i = 0; i < 14; i++ )
711 {
712 j = i % 7;
713 k = i < 7;
714
715 if( verbose != 0 )
716 printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 );
717
718 if( j == 5 || j == 6 )
719 {
720 memset( buf, '\xAA', buflen = 131 );
721 sha4_hmac_starts( &ctx, buf, buflen, k );
722 }
723 else
724 sha4_hmac_starts( &ctx, sha4_hmac_test_key[j],
725 sha4_hmac_test_keylen[j], k );
726
727 sha4_hmac_update( &ctx, sha4_hmac_test_buf[j],
728 sha4_hmac_test_buflen[j] );
729
730 sha4_hmac_finish( &ctx, sha4sum );
731
732 buflen = ( j == 4 ) ? 16 : 64 - k * 16;
733
734 if( memcmp( sha4sum, sha4_hmac_test_sum[i], buflen ) != 0 )
735 {
736 if( verbose != 0 )
737 printf( "failed\n" );
738
739 return( 1 );
740 }
741
742 if( verbose != 0 )
743 printf( "passed\n" );
744 }
745
746 if( verbose != 0 )
747 printf( "\n" );
748
749 return( 0 );
750}
751
752#endif
753
754#endif