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