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