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