blob: cf20d0131afcf91fb42cb49387c2d13440818734 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
27 *
28 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
29 */
30
Paul Bakker40e46942009-01-03 21:51:57 +000031#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Paul Bakker40e46942009-01-03 21:51:57 +000033#if defined(POLARSSL_SHA4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker40e46942009-01-03 21:51:57 +000035#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
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 */
74static 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 */
121void 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
Paul Bakkerff60ee62010-03-16 21:09:09 +0000154static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000155{
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 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000226void sha4_update( sha4_context *ctx, const unsigned char *input, int ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000227{
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
266static 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 */
281void 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 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000317void sha4( const unsigned char *input, int ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000318 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 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000332int sha4_file( const char *path, unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000333{
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 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000364void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, int keylen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000365 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 */
395void sha4_hmac_update( sha4_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000396 const unsigned char *input, int ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000397{
398 sha4_update( ctx, input, ilen );
399}
400
401/*
402 * SHA-512 HMAC final digest
403 */
404void 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/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000422 * SHA-512 HMAC context reset
423 */
424void sha4_hmac_reset( sha4_context *ctx )
425{
426 sha4_starts( ctx, ctx->is384 );
427 sha4_update( ctx, ctx->ipad, 128 );
428}
429
430/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 * output = HMAC-SHA-512( hmac key, input buffer )
432 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000433void sha4_hmac( const unsigned char *key, int keylen,
434 const unsigned char *input, int ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000435 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
Paul Bakker40e46942009-01-03 21:51:57 +0000446#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
448/*
449 * FIPS-180-2 test vectors
450 */
451static unsigned char sha4_test_buf[3][113] =
452{
453 { "abc" },
454 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
455 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
456 { "" }
457};
458
459static const int sha4_test_buflen[3] =
460{
461 3, 112, 1000
462};
463
464static 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 */
520static 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
535static const int sha4_hmac_test_keylen[7] =
536{
537 20, 4, 20, 25, 20, 131, 131
538};
539
540static 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
561static const int sha4_hmac_test_buflen[7] =
562{
563 8, 28, 50, 50, 20, 54, 152
564};
565
566static 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 */
668int 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