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