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