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