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