9e201f86addc3702fceb740291ab7925d0c7e8fb
[iotcloud.git] / version2 / src / C / pbkdf2-sha256.cc
1 /*
2  *  FIPS-180-2 compliant SHA-256 implementation
3  *
4  *  Copyright (C) 2006-2010, 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-256 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 <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include "pbkdf2-sha256.h"
35
36 typedef struct {
37         unsigned long total[2]; /*!< number of bytes processed  */
38         unsigned long state[8]; /*!< intermediate digest state  */
39         unsigned char buffer[64];       /*!< data block being processed */
40
41         unsigned char ipad[64]; /*!< HMAC: inner padding        */
42         unsigned char opad[64]; /*!< HMAC: outer padding        */
43         int is224;              /*!< 0 => SHA-256, else SHA-224 */
44 } sha2_context;
45
46 /*
47  * 32-bit integer manipulation macros (big endian)
48  */
49 #ifndef GET_ULONG_BE
50 #define GET_ULONG_BE(n,b,i)                             \
51 {                                                       \
52     (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
53         | ( (unsigned long) (b)[(i) + 1] << 16 )        \
54         | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
55         | ( (unsigned long) (b)[(i) + 3]       );       \
56 }
57 #endif
58
59 #ifndef PUT_ULONG_BE
60 #define PUT_ULONG_BE(n,b,i)                             \
61 {                                                       \
62     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
63     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
64     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
65     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
66 }
67 #endif
68
69 /*
70  * SHA-256 context setup
71  */
72 void sha2_starts( sha2_context *ctx, int is224 )
73 {
74     ctx->total[0] = 0;
75     ctx->total[1] = 0;
76
77     if( is224 == 0 )
78     {
79         /* SHA-256 */
80         ctx->state[0] = 0x6A09E667;
81         ctx->state[1] = 0xBB67AE85;
82         ctx->state[2] = 0x3C6EF372;
83         ctx->state[3] = 0xA54FF53A;
84         ctx->state[4] = 0x510E527F;
85         ctx->state[5] = 0x9B05688C;
86         ctx->state[6] = 0x1F83D9AB;
87         ctx->state[7] = 0x5BE0CD19;
88     }
89     else
90     {
91         /* SHA-224 */
92         ctx->state[0] = 0xC1059ED8;
93         ctx->state[1] = 0x367CD507;
94         ctx->state[2] = 0x3070DD17;
95         ctx->state[3] = 0xF70E5939;
96         ctx->state[4] = 0xFFC00B31;
97         ctx->state[5] = 0x68581511;
98         ctx->state[6] = 0x64F98FA7;
99         ctx->state[7] = 0xBEFA4FA4;
100     }
101
102     ctx->is224 = is224;
103 }
104
105 static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
106 {
107     unsigned long temp1, temp2, W[64];
108     unsigned long A, B, C, D, E, F, G, H;
109
110     GET_ULONG_BE( W[ 0], data,  0 );
111     GET_ULONG_BE( W[ 1], data,  4 );
112     GET_ULONG_BE( W[ 2], data,  8 );
113     GET_ULONG_BE( W[ 3], data, 12 );
114     GET_ULONG_BE( W[ 4], data, 16 );
115     GET_ULONG_BE( W[ 5], data, 20 );
116     GET_ULONG_BE( W[ 6], data, 24 );
117     GET_ULONG_BE( W[ 7], data, 28 );
118     GET_ULONG_BE( W[ 8], data, 32 );
119     GET_ULONG_BE( W[ 9], data, 36 );
120     GET_ULONG_BE( W[10], data, 40 );
121     GET_ULONG_BE( W[11], data, 44 );
122     GET_ULONG_BE( W[12], data, 48 );
123     GET_ULONG_BE( W[13], data, 52 );
124     GET_ULONG_BE( W[14], data, 56 );
125     GET_ULONG_BE( W[15], data, 60 );
126
127 #define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
128 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
129
130 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
131 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
132
133 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
134 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
135
136 #define F0(x,y,z) ((x & y) | (z & (x | y)))
137 #define F1(x,y,z) (z ^ (x & (y ^ z)))
138
139 #define R(t)                                    \
140 (                                               \
141     W[t] = S1(W[t -  2]) + W[t -  7] +          \
142            S0(W[t - 15]) + W[t - 16]            \
143 )
144
145 #define P(a,b,c,d,e,f,g,h,x,K)                  \
146 {                                               \
147     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
148     temp2 = S2(a) + F0(a,b,c);                  \
149     d += temp1; h = temp1 + temp2;              \
150 }
151
152         A = ctx->state[0];
153         B = ctx->state[1];
154         C = ctx->state[2];
155         D = ctx->state[3];
156         E = ctx->state[4];
157         F = ctx->state[5];
158         G = ctx->state[6];
159         H = ctx->state[7];
160
161     P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
162     P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
163     P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
164     P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
165     P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
166     P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
167     P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
168     P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
169     P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
170     P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
171     P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
172     P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
173     P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
174     P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
175     P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
176     P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
177     P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
178     P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
179     P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
180     P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
181     P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
182     P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
183     P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
184     P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
185     P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
186     P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
187     P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
188     P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
189     P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
190     P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
191     P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
192     P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
193     P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
194     P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
195     P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
196     P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
197     P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
198     P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
199     P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
200     P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
201     P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
202     P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
203     P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
204     P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
205     P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
206     P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
207     P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
208     P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
209     P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
210     P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
211     P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
212     P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
213     P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
214     P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
215     P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
216     P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
217     P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
218     P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
219     P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
220     P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
221     P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
222     P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
223     P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
224     P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
225
226     ctx->state[0] += A;
227     ctx->state[1] += B;
228     ctx->state[2] += C;
229     ctx->state[3] += D;
230     ctx->state[4] += E;
231     ctx->state[5] += F;
232     ctx->state[6] += G;
233     ctx->state[7] += H;
234 }
235
236 /*
237  * SHA-256 process buffer
238  */
239 void sha2_update( sha2_context *ctx, const unsigned char *input, size_t ilen )
240 {
241     size_t fill;
242     unsigned long left;
243
244     if( ilen <= 0 )
245         return;
246
247     left = ctx->total[0] & 0x3F;
248     fill = 64 - left;
249
250     ctx->total[0] += (unsigned long) ilen;
251     ctx->total[0] &= 0xFFFFFFFF;
252
253     if( ctx->total[0] < (unsigned long) ilen )
254         ctx->total[1]++;
255
256     if( left && ilen >= fill )
257     {
258         memcpy( (void *) (ctx->buffer + left),
259                 (void *) input, fill );
260         sha2_process( ctx, ctx->buffer );
261         input += fill;
262         ilen  -= fill;
263         left = 0;
264     }
265
266     while( ilen >= 64 )
267     {
268         sha2_process( ctx, input );
269         input += 64;
270         ilen  -= 64;
271     }
272
273     if( ilen > 0 )
274     {
275         memcpy( (void *) (ctx->buffer + left),
276                 (void *) input, ilen );
277     }
278 }
279
280 static const unsigned char sha2_padding[64] =
281 {
282  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
284     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
285     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
286 };
287
288 /*
289  * SHA-256 final digest
290  */
291 void sha2_finish( sha2_context *ctx, unsigned char output[32] )
292 {
293     unsigned long last, padn;
294     unsigned long high, low;
295     unsigned char msglen[8];
296
297     high = ( ctx->total[0] >> 29 )
298          | ( ctx->total[1] <<  3 );
299     low  = ( ctx->total[0] <<  3 );
300
301     PUT_ULONG_BE( high, msglen, 0 );
302     PUT_ULONG_BE( low,  msglen, 4 );
303
304     last = ctx->total[0] & 0x3F;
305     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
306
307     sha2_update( ctx, (unsigned char *) sha2_padding, padn );
308     sha2_update( ctx, msglen, 8 );
309
310     PUT_ULONG_BE( ctx->state[0], output,  0 );
311     PUT_ULONG_BE( ctx->state[1], output,  4 );
312     PUT_ULONG_BE( ctx->state[2], output,  8 );
313     PUT_ULONG_BE( ctx->state[3], output, 12 );
314     PUT_ULONG_BE( ctx->state[4], output, 16 );
315     PUT_ULONG_BE( ctx->state[5], output, 20 );
316     PUT_ULONG_BE( ctx->state[6], output, 24 );
317
318     if( ctx->is224 == 0 )
319         PUT_ULONG_BE( ctx->state[7], output, 28 );
320 }
321
322 /*
323  * output = SHA-256( input buffer )
324  */
325 void sha2( const unsigned char *input, size_t ilen,
326            unsigned char output[32], int is224 )
327 {
328     sha2_context ctx;
329
330     sha2_starts( &ctx, is224 );
331     sha2_update( &ctx, input, ilen );
332     sha2_finish( &ctx, output );
333
334     memset( &ctx, 0, sizeof( sha2_context ) );
335 }
336
337 /*
338  * SHA-256 HMAC context setup
339  */
340 void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, size_t keylen,
341                        int is224 )
342 {
343     size_t i;
344     unsigned char sum[32];
345
346     if( keylen > 64 )
347     {
348         sha2( key, keylen, sum, is224 );
349         keylen = ( is224 ) ? 28 : 32;
350         key = sum;
351     }
352
353     memset( ctx->ipad, 0x36, 64 );
354     memset( ctx->opad, 0x5C, 64 );
355
356     for( i = 0; i < keylen; i++ )
357     {
358         ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
359         ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
360     }
361
362     sha2_starts( ctx, is224 );
363     sha2_update( ctx, ctx->ipad, 64 );
364
365     memset( sum, 0, sizeof( sum ) );
366 }
367
368 /*
369  * SHA-256 HMAC process buffer
370  */
371 void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, size_t ilen )
372 {
373     sha2_update( ctx, input, ilen );
374 }
375
376 /*
377  * SHA-256 HMAC final digest
378  */
379 void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] )
380 {
381     int is224, hlen;
382     unsigned char tmpbuf[32];
383
384     is224 = ctx->is224;
385     hlen = ( is224 == 0 ) ? 32 : 28;
386
387     sha2_finish( ctx, tmpbuf );
388     sha2_starts( ctx, is224 );
389     sha2_update( ctx, ctx->opad, 64 );
390     sha2_update( ctx, tmpbuf, hlen );
391     sha2_finish( ctx, output );
392
393     memset( tmpbuf, 0, sizeof( tmpbuf ) );
394 }
395
396 /*
397  * SHA-256 HMAC context reset
398  */
399 void sha2_hmac_reset( sha2_context *ctx )
400 {
401     sha2_starts( ctx, ctx->is224 );
402     sha2_update( ctx, ctx->ipad, 64 );
403 }
404
405 /*
406  * output = HMAC-SHA-256( hmac key, input buffer )
407  */
408 void sha2_hmac( const unsigned char *key, size_t keylen,
409                 const unsigned char *input, size_t ilen,
410                 unsigned char output[32], int is224 )
411 {
412     sha2_context ctx;
413
414     sha2_hmac_starts( &ctx, key, keylen, is224 );
415     sha2_hmac_update( &ctx, input, ilen );
416     sha2_hmac_finish( &ctx, output );
417
418     memset( &ctx, 0, sizeof( sha2_context ) );
419 }
420
421
422
423
424
425 #ifndef min
426 #define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
427 #endif
428
429 void PKCS5_PBKDF2_HMAC(unsigned char *password, size_t plen,
430     unsigned char *salt, size_t slen,
431     const unsigned long iteration_count, const unsigned long key_length,
432     unsigned char *output)
433 {
434         sha2_context ctx;
435         sha2_starts(&ctx, 0);
436
437         // Size of the generated digest
438         unsigned char md_size = 32;
439         unsigned char md1[32];
440         unsigned char work[32];
441
442         unsigned long counter = 1;
443         unsigned long generated_key_length = 0;
444         while (generated_key_length < key_length) {
445                 // U1 ends up in md1 and work
446                 unsigned char c[4];
447                 c[0] = (counter >> 24) & 0xff;
448                 c[1] = (counter >> 16) & 0xff;
449                 c[2] = (counter >> 8) & 0xff;
450                 c[3] = (counter >> 0) & 0xff;
451
452                 sha2_hmac_starts(&ctx, password, plen, 0);
453                 sha2_hmac_update(&ctx, salt, slen);
454                 sha2_hmac_update(&ctx, c, 4);
455                 sha2_hmac_finish(&ctx, md1);
456                 memcpy(work, md1, md_size);
457
458                 unsigned long ic = 1;
459                 for (ic = 1; ic < iteration_count; ic++) {
460                         // U2 ends up in md1
461                         sha2_hmac_starts(&ctx, password, plen, 0);
462                         sha2_hmac_update(&ctx, md1, md_size);
463                         sha2_hmac_finish(&ctx, md1);
464                         // U1 xor U2
465                         unsigned long i = 0;
466                         for (i = 0; i < md_size; i++) {
467                                 work[i] ^= md1[i];
468                         }
469                         // and so on until iteration_count
470                 }
471
472                 // Copy the generated bytes to the key
473                 unsigned long bytes_to_write =
474                     min((key_length - generated_key_length), md_size);
475                 memcpy(output + generated_key_length, work, bytes_to_write);
476                 generated_key_length += bytes_to_write;
477                 ++counter;
478         }
479 }
480
481
482
483
484
485
486
487
488
489 #ifdef TEST
490 /*
491  * FIPS-180-2 test vectors
492  */
493 static unsigned char sha2_test_buf[3][57] = 
494 {
495     { "abc" },
496     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
497     { "" }
498 };
499
500 static const int sha2_test_buflen[3] =
501 {
502     3, 56, 1000
503 };
504
505 static const unsigned char sha2_test_sum[6][32] =
506 {
507     /*
508      * SHA-224 test vectors
509      */
510     { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
511       0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
512       0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
513       0xE3, 0x6C, 0x9D, 0xA7 },
514     { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
515       0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
516       0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
517       0x52, 0x52, 0x25, 0x25 },
518     { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
519       0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
520       0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
521       0x4E, 0xE7, 0xAD, 0x67 },
522
523     /*
524      * SHA-256 test vectors
525      */
526     { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
527       0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
528       0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
529       0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
530     { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
531       0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
532       0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
533       0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
534     { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
535       0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
536       0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
537       0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
538 };
539
540 /*
541  * RFC 4231 test vectors
542  */
543 static unsigned char sha2_hmac_test_key[7][26] = {
544         {"\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
545                     "\x0B\x0B\x0B\x0B"},
546         {"Jefe"},
547         {"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
548                     "\xAA\xAA\xAA\xAA"},
549         {"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
550                     "\x11\x12\x13\x14\x15\x16\x17\x18\x19"},
551         {"\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
552                     "\x0C\x0C\x0C\x0C"},
553         {""},                   /* 0xAA 131 times */
554         {""}
555 };
556
557 static const int sha2_hmac_test_keylen[7] = {
558         20, 4, 20, 25, 20, 131, 131
559 };
560
561 static unsigned char sha2_hmac_test_buf[7][153] =
562 {
563     { "Hi There" },
564     { "what do ya want for nothing?" },
565     { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
566       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
567       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
568       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
569       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
570     { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
571       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
572       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
573       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
574       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
575     { "Test With Truncation" },
576     { "Test Using Larger Than Block-Size Key - Hash Key First" },
577     { "This is a test using a larger than block-size key "
578       "and a larger than block-size data. The key needs to "
579       "be hashed before being used by the HMAC algorithm." }
580 };
581
582 static const int sha2_hmac_test_buflen[7] =
583 {
584     8, 28, 50, 50, 20, 54, 152
585 };
586
587 static const unsigned char sha2_hmac_test_sum[14][32] =
588 {
589     /*
590      * HMAC-SHA-224 test vectors
591      */
592     { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
593       0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
594       0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
595       0x53, 0x68, 0x4B, 0x22 },
596     { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
597       0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
598       0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
599       0x8F, 0xD0, 0x5E, 0x44 },
600     { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
601       0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
602       0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
603       0xEC, 0x83, 0x33, 0xEA },
604     { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
605       0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
606       0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
607       0xE7, 0xAF, 0xEC, 0x5A },
608     { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
609       0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
610     { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
611       0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
612       0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
613       0x3F, 0xA6, 0x87, 0x0E },
614     { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
615       0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
616       0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
617       0xF6, 0xF5, 0x65, 0xD1 },
618
619     /*
620      * HMAC-SHA-256 test vectors
621      */
622     { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
623       0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
624       0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
625       0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
626     { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
627       0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
628       0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
629       0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
630     { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
631       0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
632       0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
633       0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
634     { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
635       0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
636       0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
637       0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
638     { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
639       0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
640     { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
641       0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
642       0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
643       0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
644     { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
645       0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
646       0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
647       0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
648 };
649 typedef struct {
650         char *t;
651         char *p;
652         int plen;
653         char *s;
654         int slen;
655         int c;
656         int dkLen;
657         char dk[1024];          // Remember to set this to max dkLen
658 } testvector;
659
660 int do_test(testvector * tv)
661 {
662         printf("Started %s\n", tv->t);
663         fflush(stdout);
664         char *key = malloc(tv->dkLen);
665         if (key == 0) {
666                 return -1;
667         }
668
669         PKCS5_PBKDF2_HMAC((unsigned char*)tv->p, tv->plen,
670                         (unsigned char*)tv->s, tv->slen, tv->c,
671                         tv->dkLen, (unsigned char*)key);
672
673         if (memcmp(tv->dk, key, tv->dkLen) != 0) {
674                 // Failed
675                 return -1;
676         }
677
678         return 0;
679 }
680
681 /*
682  * Checkup routine
683  */
684 int main()
685 {
686         int verbose = 1;
687         int i, j, k, buflen;
688         unsigned char buf[1024];
689         unsigned char sha2sum[32];
690         sha2_context ctx;
691
692         for (i = 0; i < 6; i++) {
693                 j = i % 3;
694                 k = i < 3;
695
696                 if (verbose != 0)
697                         printf("  SHA-%d test #%d: ", 256 - k * 32, j + 1);
698
699                 sha2_starts(&ctx, k);
700
701                 if (j == 2) {
702                         memset(buf, 'a', buflen = 1000);
703
704                         for (j = 0; j < 1000; j++)
705                                 sha2_update(&ctx, buf, buflen);
706                 } else
707                         sha2_update(&ctx, sha2_test_buf[j],
708                             sha2_test_buflen[j]);
709
710                 sha2_finish(&ctx, sha2sum);
711
712                 if (memcmp(sha2sum, sha2_test_sum[i], 32 - k * 4) != 0) {
713                         if (verbose != 0)
714                                 printf("failed\n");
715
716                         return (1);
717                 }
718
719                 if (verbose != 0)
720                         printf("passed\n");
721         }
722
723         if (verbose != 0)
724                 printf("\n");
725
726         for (i = 0; i < 14; i++) {
727                 j = i % 7;
728                 k = i < 7;
729
730                 if (verbose != 0)
731                         printf("  HMAC-SHA-%d test #%d: ", 256 - k * 32,
732                             j + 1);
733
734                 if (j == 5 || j == 6) {
735                         memset(buf, '\xAA', buflen = 131);
736                         sha2_hmac_starts(&ctx, buf, buflen, k);
737                 } else
738                         sha2_hmac_starts(&ctx, sha2_hmac_test_key[j],
739                             sha2_hmac_test_keylen[j], k);
740
741                 sha2_hmac_update(&ctx, sha2_hmac_test_buf[j],
742                     sha2_hmac_test_buflen[j]);
743
744                 sha2_hmac_finish(&ctx, sha2sum);
745
746                 buflen = (j == 4) ? 16 : 32 - k * 4;
747
748                 if (memcmp(sha2sum, sha2_hmac_test_sum[i], buflen) != 0) {
749                         if (verbose != 0)
750                                 printf("failed\n");
751
752                         return (1);
753                 }
754
755                 if (verbose != 0)
756                         printf("passed\n");
757         }
758
759         if (verbose != 0)
760                 printf("\n");
761
762         testvector *tv = 0;
763         int res = 0;
764
765         testvector t1 = {
766                 "Test 1",
767                 "password", 8, "salt", 4, 1, 32,
768                 .dk = { 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c,
769                         0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37,
770                         0xa8, 0x65, 0x48, 0xc9, 0x2c, 0xcc, 0x35, 0x48,
771                         0x08, 0x05, 0x98, 0x7c, 0xb7, 0x0b, 0xe1, 0x7b }
772         };
773
774         tv = &t1;
775         res = do_test(tv);
776         if (res != 0) {
777                 printf("%s failed\n", tv->t);
778                 return res;
779         }
780
781         testvector t2 = {
782                 "Test 2",
783                 "password", 8, "salt", 4, 2, 32, {
784                         0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
785                         0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
786                         0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf,
787                         0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43 }
788         };
789
790         tv = &t2;
791         res = do_test(tv);
792         if (res != 0) {
793                 printf("%s failed\n", tv->t);
794                 return res;
795         }
796
797         testvector t3 = {
798                 "Test 3",
799                 "password", 8, "salt", 4, 4096, 32, {
800                         0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41,
801                         0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d,
802                         0x96, 0x28, 0x93, 0xa0, 0x01, 0xce, 0x4e, 0x11,
803                         0xa4, 0x96, 0x38, 0x73, 0xaa, 0x98, 0x13, 0x4a }
804         };
805
806         tv = &t3;
807         res = do_test(tv);
808         if (res != 0) {
809                 printf("%s failed\n", tv->t);
810                 return res;
811         }
812
813         testvector t4 = {
814                 "Test 4",
815                 "password", 8, "salt", 4, 16777216, 32, {
816                         0xcf, 0x81, 0xc6, 0x6f, 0xe8, 0xcf, 0xc0, 0x4d,
817                         0x1f, 0x31, 0xec, 0xb6, 0x5d, 0xab, 0x40, 0x89,
818                         0xf7, 0xf1, 0x79, 0xe8, 0x9b, 0x3b, 0x0b, 0xcb,
819                         0x17, 0xad, 0x10, 0xe3, 0xac, 0x6e, 0xba, 0x46 }
820         };
821
822         tv = &t4;
823         // res = do_test(tv);
824         if (res != 0) {
825                 printf("%s failed\n", tv->t);
826                 return res;
827         }
828
829         testvector t5 = {
830                 "Test 5",
831                 "passwordPASSWORDpassword", 24,
832                 "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096, 40, {
833                         0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f,
834                         0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf,
835                         0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
836                         0x1c, 0x4e, 0x2a, 0x1f, 0xb8, 0xdd, 0x53, 0xe1,
837                         0xc6, 0x35, 0x51, 0x8c, 0x7d, 0xac, 0x47, 0xe9 }
838         };
839
840         tv = &t5;
841         res = do_test(tv);
842         if (res != 0) {
843                 printf("%s failed\n", tv->t);
844                 return res;
845         }
846
847         testvector t6 = {
848                 "Test 6",
849                 "pass\0word", 9, "sa\0lt", 5, 4096, 16, {
850                         0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89,
851                         0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87 }
852         };
853
854         tv = &t6;
855         res = do_test(tv);
856         if (res != 0) {
857                 printf("%s failed\n", tv->t);
858                 return res;
859         }
860
861         return (0);
862 }
863
864 #endif