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