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