space hacks
[iotcloud.git] / version2 / src / C / pbkdf2-sha256.cpp
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
781         tv = &t2;
782         res = do_test(tv);
783         if (res != 0) {
784                 printf("%s failed\n", tv->t);
785                 return res;
786         }
787
788         testvector t3 = {
789                 "Test 3",
790                 "password", 8, "salt", 4, 4096, 32, {
791                         0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41,
792                         0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d,
793                         0x96, 0x28, 0x93, 0xa0, 0x01, 0xce, 0x4e, 0x11,
794                         0xa4, 0x96, 0x38, 0x73, 0xaa, 0x98, 0x13, 0x4a
795                 }
796         };
797
798         tv = &t3;
799         res = do_test(tv);
800         if (res != 0) {
801                 printf("%s failed\n", tv->t);
802                 return res;
803         }
804
805         testvector t4 = {
806                 "Test 4",
807                 "password", 8, "salt", 4, 16777216, 32, {
808                         0xcf, 0x81, 0xc6, 0x6f, 0xe8, 0xcf, 0xc0, 0x4d,
809                         0x1f, 0x31, 0xec, 0xb6, 0x5d, 0xab, 0x40, 0x89,
810                         0xf7, 0xf1, 0x79, 0xe8, 0x9b, 0x3b, 0x0b, 0xcb,
811                         0x17, 0xad, 0x10, 0xe3, 0xac, 0x6e, 0xba, 0x46
812                 }
813         };
814
815         tv = &t4;
816         // res = do_test(tv);
817         if (res != 0) {
818                 printf("%s failed\n", tv->t);
819                 return res;
820         }
821
822         testvector t5 = {
823                 "Test 5",
824                 "passwordPASSWORDpassword", 24,
825                 "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096, 40, {
826                         0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f,
827                         0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf,
828                         0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
829                         0x1c, 0x4e, 0x2a, 0x1f, 0xb8, 0xdd, 0x53, 0xe1,
830                         0xc6, 0x35, 0x51, 0x8c, 0x7d, 0xac, 0x47, 0xe9
831                 }
832         };
833
834         tv = &t5;
835         res = do_test(tv);
836         if (res != 0) {
837                 printf("%s failed\n", tv->t);
838                 return res;
839         }
840
841         testvector t6 = {
842                 "Test 6",
843                 "pass\0word", 9, "sa\0lt", 5, 4096, 16, {
844                         0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89,
845                         0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87
846                 }
847         };
848
849         tv = &t6;
850         res = do_test(tv);
851         if (res != 0) {
852                 printf("%s failed\n", tv->t);
853                 return res;
854         }
855
856         return (0);
857 }
858
859 #endif