blob: 63d98099fc9f30785a12c0c60f96e17680059718 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Paul Bakker90995b52013-06-24 19:20:35 +02004 * Copyright (C) 2006-2013, 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
Paul Bakker90995b52013-06-24 19:20:35 +020041#if !defined(POLARSSL_SHA4_ALT)
42
Paul Bakker5121ce52009-01-03 21:22:43 +000043/*
44 * 64-bit integer manipulation macros (big endian)
45 */
46#ifndef GET_UINT64_BE
47#define GET_UINT64_BE(n,b,i) \
48{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000049 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
50 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
51 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
52 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
53 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
54 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
55 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
56 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000057}
58#endif
59
60#ifndef PUT_UINT64_BE
61#define PUT_UINT64_BE(n,b,i) \
62{ \
63 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
64 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
65 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
66 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
67 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
68 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
69 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
70 (b)[(i) + 7] = (unsigned char) ( (n) ); \
71}
72#endif
73
74/*
75 * Round constants
76 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000077static const uint64_t K[80] =
Paul Bakker5121ce52009-01-03 21:22:43 +000078{
79 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
80 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
81 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
82 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
83 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
84 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
85 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
86 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
87 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
88 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
89 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
90 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
91 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
92 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
93 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
94 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
95 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
96 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
97 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
98 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
99 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
100 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
101 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
102 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
103 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
104 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
105 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
106 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
107 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
108 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
109 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
110 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
111 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
112 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
113 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
114 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
115 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
116 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
117 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
118 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
119};
120
121/*
122 * SHA-512 context setup
123 */
124void sha4_starts( sha4_context *ctx, int is384 )
125{
126 ctx->total[0] = 0;
127 ctx->total[1] = 0;
128
129 if( is384 == 0 )
130 {
131 /* SHA-512 */
132 ctx->state[0] = UL64(0x6A09E667F3BCC908);
133 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
134 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
135 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
136 ctx->state[4] = UL64(0x510E527FADE682D1);
137 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
138 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
139 ctx->state[7] = UL64(0x5BE0CD19137E2179);
140 }
141 else
142 {
143 /* SHA-384 */
144 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
145 ctx->state[1] = UL64(0x629A292A367CD507);
146 ctx->state[2] = UL64(0x9159015A3070DD17);
147 ctx->state[3] = UL64(0x152FECD8F70E5939);
148 ctx->state[4] = UL64(0x67332667FFC00B31);
149 ctx->state[5] = UL64(0x8EB44A8768581511);
150 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
151 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
152 }
153
154 ctx->is384 = is384;
155}
156
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100157void sha4_process( sha4_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000158{
159 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000160 uint64_t temp1, temp2, W[80];
161 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
163#define SHR(x,n) (x >> n)
164#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
165
166#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
167#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
168
169#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
170#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
171
172#define F0(x,y,z) ((x & y) | (z & (x | y)))
173#define F1(x,y,z) (z ^ (x & (y ^ z)))
174
175#define P(a,b,c,d,e,f,g,h,x,K) \
176{ \
177 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
178 temp2 = S2(a) + F0(a,b,c); \
179 d += temp1; h = temp1 + temp2; \
180}
181
182 for( i = 0; i < 16; i++ )
183 {
184 GET_UINT64_BE( W[i], data, i << 3 );
185 }
186
187 for( ; i < 80; i++ )
188 {
189 W[i] = S1(W[i - 2]) + W[i - 7] +
190 S0(W[i - 15]) + W[i - 16];
191 }
192
193 A = ctx->state[0];
194 B = ctx->state[1];
195 C = ctx->state[2];
196 D = ctx->state[3];
197 E = ctx->state[4];
198 F = ctx->state[5];
199 G = ctx->state[6];
200 H = ctx->state[7];
201 i = 0;
202
203 do
204 {
205 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
206 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
207 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
208 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
209 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
210 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
211 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
212 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
213 }
214 while( i < 80 );
215
216 ctx->state[0] += A;
217 ctx->state[1] += B;
218 ctx->state[2] += C;
219 ctx->state[3] += D;
220 ctx->state[4] += E;
221 ctx->state[5] += F;
222 ctx->state[6] += G;
223 ctx->state[7] += H;
224}
225
226/*
227 * SHA-512 process buffer
228 */
Paul Bakker23986e52011-04-24 08:57:21 +0000229void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000230{
Paul Bakker23986e52011-04-24 08:57:21 +0000231 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000232 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
234 if( ilen <= 0 )
235 return;
236
Paul Bakkerb8213a12011-07-11 08:16:18 +0000237 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000238 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000239
Paul Bakker5c2364c2012-10-01 14:41:15 +0000240 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000241
Paul Bakker5c2364c2012-10-01 14:41:15 +0000242 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000243 ctx->total[1]++;
244
245 if( left && ilen >= fill )
246 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200247 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000248 sha4_process( ctx, ctx->buffer );
249 input += fill;
250 ilen -= fill;
251 left = 0;
252 }
253
254 while( ilen >= 128 )
255 {
256 sha4_process( ctx, input );
257 input += 128;
258 ilen -= 128;
259 }
260
261 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200262 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000263}
264
265static const unsigned char sha4_padding[128] =
266{
267 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
275};
276
277/*
278 * SHA-512 final digest
279 */
280void sha4_finish( sha4_context *ctx, unsigned char output[64] )
281{
Paul Bakker27fdf462011-06-09 13:55:13 +0000282 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000283 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 unsigned char msglen[16];
285
286 high = ( ctx->total[0] >> 61 )
287 | ( ctx->total[1] << 3 );
288 low = ( ctx->total[0] << 3 );
289
290 PUT_UINT64_BE( high, msglen, 0 );
291 PUT_UINT64_BE( low, msglen, 8 );
292
Paul Bakker27fdf462011-06-09 13:55:13 +0000293 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
295
Paul Bakker3c2122f2013-06-24 19:03:14 +0200296 sha4_update( ctx, sha4_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000297 sha4_update( ctx, msglen, 16 );
298
299 PUT_UINT64_BE( ctx->state[0], output, 0 );
300 PUT_UINT64_BE( ctx->state[1], output, 8 );
301 PUT_UINT64_BE( ctx->state[2], output, 16 );
302 PUT_UINT64_BE( ctx->state[3], output, 24 );
303 PUT_UINT64_BE( ctx->state[4], output, 32 );
304 PUT_UINT64_BE( ctx->state[5], output, 40 );
305
306 if( ctx->is384 == 0 )
307 {
308 PUT_UINT64_BE( ctx->state[6], output, 48 );
309 PUT_UINT64_BE( ctx->state[7], output, 56 );
310 }
311}
312
Paul Bakker90995b52013-06-24 19:20:35 +0200313#endif /* !POLARSSL_SHA4_ALT */
314
Paul Bakker5121ce52009-01-03 21:22:43 +0000315/*
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