PolarSSL v1.2.10
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 #if !defined(POLARSSL_SHA4_ALT)
42 
43 /*
44  * 64-bit integer manipulation macros (big endian)
45  */
46 #ifndef GET_UINT64_BE
47 #define GET_UINT64_BE(n,b,i) \
48 { \
49  (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] ); \
57 }
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  */
77 static const uint64_t K[80] =
78 {
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  */
124 void 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 
157 static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
158 {
159  int i;
160  uint64_t temp1, temp2, W[80];
161  uint64_t A, B, C, D, E, F, G, H;
162 
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  */
229 void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen )
230 {
231  size_t fill;
232  unsigned int left;
233 
234  if( ilen <= 0 )
235  return;
236 
237  left = (unsigned int) (ctx->total[0] & 0x7F);
238  fill = 128 - left;
239 
240  ctx->total[0] += (uint64_t) ilen;
241 
242  if( ctx->total[0] < (uint64_t) ilen )
243  ctx->total[1]++;
244 
245  if( left && ilen >= fill )
246  {
247  memcpy( (void *) (ctx->buffer + left), input, fill );
248  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 )
262  memcpy( (void *) (ctx->buffer + left), input, ilen );
263 }
264 
265 static 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  */
280 void sha4_finish( sha4_context *ctx, unsigned char output[64] )
281 {
282  size_t last, padn;
283  uint64_t high, low;
284  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 
293  last = (size_t)( ctx->total[0] & 0x7F );
294  padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
295 
296  sha4_update( ctx, sha4_padding, padn );
297  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 
313 #endif /* !POLARSSL_SHA4_ALT */
314 
315 /*
316  * output = SHA-512( input buffer )
317  */
318 void sha4( const unsigned char *input, size_t ilen,
319  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 
330 #if defined(POLARSSL_FS_IO)
331 /*
332  * output = SHA-512( file contents )
333  */
334 int sha4_file( const char *path, unsigned char output[64], int is384 )
335 {
336  FILE *f;
337  size_t n;
338  sha4_context ctx;
339  unsigned char buf[1024];
340 
341  if( ( f = fopen( path, "rb" ) ) == NULL )
343 
344  sha4_starts( &ctx, is384 );
345 
346  while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
347  sha4_update( &ctx, buf, n );
348 
349  sha4_finish( &ctx, output );
350 
351  memset( &ctx, 0, sizeof( sha4_context ) );
352 
353  if( ferror( f ) != 0 )
354  {
355  fclose( f );
357  }
358 
359  fclose( f );
360  return( 0 );
361 }
362 #endif /* POLARSSL_FS_IO */
363 
364 /*
365  * SHA-512 HMAC context setup
366  */
367 void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, size_t keylen,
368  int is384 )
369 {
370  size_t i;
371  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  */
398 void sha4_hmac_update( sha4_context *ctx,
399  const unsigned char *input, size_t ilen )
400 {
401  sha4_update( ctx, input, ilen );
402 }
403 
404 /*
405  * SHA-512 HMAC final digest
406  */
407 void 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 /*
425  * SHA-512 HMAC context reset
426  */
427 void sha4_hmac_reset( sha4_context *ctx )
428 {
429  sha4_starts( ctx, ctx->is384 );
430  sha4_update( ctx, ctx->ipad, 128 );
431 }
432 
433 /*
434  * output = HMAC-SHA-512( hmac key, input buffer )
435  */
436 void sha4_hmac( const unsigned char *key, size_t keylen,
437  const unsigned char *input, size_t ilen,
438  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 
449 #if defined(POLARSSL_SELF_TEST)
450 
451 /*
452  * FIPS-180-2 test vectors
453  */
454 static unsigned char sha4_test_buf[3][113] =
455 {
456  { "abc" },
457  { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
458  "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
459  { "" }
460 };
461 
462 static const int sha4_test_buflen[3] =
463 {
464  3, 112, 1000
465 };
466 
467 static 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  */
523 static 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 
538 static const int sha4_hmac_test_keylen[7] =
539 {
540  20, 4, 20, 25, 20, 131, 131
541 };
542 
543 static 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 
564 static const int sha4_hmac_test_buflen[7] =
565 {
566  8, 28, 50, 50, 20, 54, 152
567 };
568 
569 static 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  */
671 int 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
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