Support arbitrary IV length with AES-GCM
[mech_eap.git] / tests / test-aes.c
1 /*
2  * Test program for AES
3  * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "crypto/crypto.h"
13 #include "crypto/aes_wrap.h"
14
15 #define BLOCK_SIZE 16
16
17 static void test_aes_perf(void)
18 {
19 #if 0 /* this did not seem to work with new compiler?! */
20 #ifdef __i386__
21 #define rdtscll(val) \
22      __asm__ __volatile__("rdtsc" : "=A" (val))
23         const int num_iters = 10;
24         int i;
25         unsigned int start, end;
26         u8 key[16], pt[16], ct[16];
27         void *ctx;
28
29         printf("keySetupEnc:");
30         for (i = 0; i < num_iters; i++) {
31                 rdtscll(start);
32                 ctx = aes_encrypt_init(key, 16);
33                 rdtscll(end);
34                 aes_encrypt_deinit(ctx);
35                 printf(" %d", end - start);
36         }
37         printf("\n");
38
39         printf("Encrypt:");
40         ctx = aes_encrypt_init(key, 16);
41         for (i = 0; i < num_iters; i++) {
42                 rdtscll(start);
43                 aes_encrypt(ctx, pt, ct);
44                 rdtscll(end);
45                 printf(" %d", end - start);
46         }
47         aes_encrypt_deinit(ctx);
48         printf("\n");
49 #endif /* __i386__ */
50 #endif
51 }
52
53
54 static int test_eax(void)
55 {
56         u8 msg[] = { 0xF7, 0xFB };
57         u8 key[] = { 0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B,
58                      0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4 };
59         u8 nonce[] = { 0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84,
60                        0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD };
61         u8 hdr[] = { 0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA };
62         u8 cipher[] = { 0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D,
63                         0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79,
64                         0x67, 0xE5 };
65         u8 data[sizeof(msg)], tag[BLOCK_SIZE];
66
67         memcpy(data, msg, sizeof(msg));
68         if (aes_128_eax_encrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
69                                 data, sizeof(data), tag)) {
70                 printf("AES-128 EAX mode encryption failed\n");
71                 return 1;
72         }
73         if (memcmp(data, cipher, sizeof(data)) != 0) {
74                 printf("AES-128 EAX mode encryption returned invalid cipher "
75                        "text\n");
76                 return 1;
77         }
78         if (memcmp(tag, cipher + sizeof(data), BLOCK_SIZE) != 0) {
79                 printf("AES-128 EAX mode encryption returned invalid tag\n");
80                 return 1;
81         }
82
83         if (aes_128_eax_decrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
84                                 data, sizeof(data), tag)) {
85                 printf("AES-128 EAX mode decryption failed\n");
86                 return 1;
87         }
88         if (memcmp(data, msg, sizeof(data)) != 0) {
89                 printf("AES-128 EAX mode decryption returned invalid plain "
90                        "text\n");
91                 return 1;
92         }
93
94         return 0;
95 }
96
97
98 static int test_cbc(void)
99 {
100         struct cbc_test_vector {
101                 u8 key[16];
102                 u8 iv[16];
103                 u8 plain[32];
104                 u8 cipher[32];
105                 size_t len;
106         } vectors[] = {
107                 {
108                         { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
109                           0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
110                         { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
111                           0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
112                         "Single block msg",
113                         { 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8,
114                           0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a },
115                         16
116                 },
117                 {
118                         { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
119                           0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
120                         { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
121                           0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
122                         { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
123                           0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
124                           0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
125                           0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
126                         { 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
127                           0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
128                           0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
129                           0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
130                         32
131                 }
132         };
133         int ret = 0;
134         u8 *buf;
135         unsigned int i;
136
137         for (i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
138                 struct cbc_test_vector *tv = &vectors[i];
139                 buf = malloc(tv->len);
140                 if (buf == NULL) {
141                         ret++;
142                         break;
143                 }
144                 memcpy(buf, tv->plain, tv->len);
145                 if (aes_128_cbc_encrypt(tv->key, tv->iv, buf, tv->len) ||
146                     memcmp(buf, tv->cipher, tv->len) != 0) {
147                         printf("AES-CBC encrypt %d failed\n", i);
148                         ret++;
149                 }
150                 memcpy(buf, tv->cipher, tv->len);
151                 if (aes_128_cbc_decrypt(tv->key, tv->iv, buf, tv->len) ||
152                     memcmp(buf, tv->plain, tv->len) != 0) {
153                         printf("AES-CBC decrypt %d failed\n", i);
154                         ret++;
155                 }
156                 free(buf);
157         }
158
159         return ret;
160 }
161
162
163 /*
164  * GCM test vectors from
165  * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
166  */
167 struct gcm_test_vector {
168         char *k;
169         char *p;
170         char *aad;
171         char *iv;
172         char *c;
173         char *t;
174 };
175
176 static const struct gcm_test_vector gcm_tests[] = {
177         {
178                 /* Test Case 1 */
179                 "00000000000000000000000000000000",
180                 "",
181                 "",
182                 "000000000000000000000000",
183                 "",
184                 "58e2fccefa7e3061367f1d57a4e7455a"
185         },
186         {
187                 /* Test Case 2 */
188                 "00000000000000000000000000000000",
189                 "00000000000000000000000000000000",
190                 "",
191                 "000000000000000000000000",
192                 "0388dace60b6a392f328c2b971b2fe78",
193                 "ab6e47d42cec13bdf53a67b21257bddf"
194         },
195         {
196                 /* Test Case 3 */
197                 "feffe9928665731c6d6a8f9467308308",
198                 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
199                 "",
200                 "cafebabefacedbaddecaf888",
201                 "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985",
202                 "4d5c2af327cd64a62cf35abd2ba6fab4"
203         },
204         {
205                 /* Test Case 4 */
206                 "feffe9928665731c6d6a8f9467308308",
207                 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
208                 "feedfacedeadbeeffeedfacedeadbeefabaddad2",
209                 "cafebabefacedbaddecaf888",
210                 "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091",
211                 "5bc94fbc3221a5db94fae95ae7121a47"
212         },
213         {
214                 /* Test Case 5 */
215                 "feffe9928665731c6d6a8f9467308308",
216                 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
217                 "feedfacedeadbeeffeedfacedeadbeefabaddad2",
218                 "cafebabefacedbad",
219                 "61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598",
220                 "3612d2e79e3b0785561be14aaca2fccb"
221         },
222         {
223                 /* Test Case 6 */
224                 "feffe9928665731c6d6a8f9467308308",
225                 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
226                 "feedfacedeadbeeffeedfacedeadbeefabaddad2",
227                 "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
228                 "8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5",
229                 "619cc5aefffe0bfa462af43c1699d050"
230         }
231 };
232
233
234 static int test_gcm(void)
235 {
236         int ret = 0;
237         int i;
238         u8 k[16], aad[32], iv[64], t[16], tag[16];
239         u8 p[64], c[64], tmp[64];
240         size_t p_len, aad_len, iv_len;
241
242         for (i = 0; i < sizeof(gcm_tests) / sizeof(gcm_tests[0]); i++) {
243                 const struct gcm_test_vector *tc = &gcm_tests[i];
244
245                 if (hexstr2bin(tc->k, k, sizeof(k))) {
246                         printf("Invalid GCM test vector %d (k)\n", i);
247                         ret++;
248                         continue;
249                 }
250
251                 p_len = os_strlen(tc->p) / 2;
252                 if (hexstr2bin(tc->p, p, p_len)) {
253                         printf("Invalid GCM test vector %d (p)\n", i);
254                         ret++;
255                         continue;
256                 }
257
258                 aad_len = os_strlen(tc->aad) / 2;
259                 if (hexstr2bin(tc->aad, aad, aad_len)) {
260                         printf("Invalid GCM test vector %d (aad)\n", i);
261                         ret++;
262                         continue;
263                 }
264
265                 iv_len = os_strlen(tc->iv) / 2;
266                 if (hexstr2bin(tc->iv, iv, iv_len)) {
267                         printf("Invalid GCM test vector %d (iv)\n", i);
268                         ret++;
269                         continue;
270                 }
271
272                 if (hexstr2bin(tc->c, c, p_len)) {
273                         printf("Invalid GCM test vector %d (c)\n", i);
274                         ret++;
275                         continue;
276                 }
277
278                 if (hexstr2bin(tc->t, t, sizeof(t))) {
279                         printf("Invalid GCM test vector %d (t)\n", i);
280                         ret++;
281                         continue;
282                 }
283
284                 if (aes_128_gcm_ae(k, iv, iv_len, p, p_len, aad, aad_len, tmp,
285                                    tag) < 0) {
286                         printf("GCM-AE failed (test case %d)\n", i);
287                         ret++;
288                         continue;
289                 }
290
291                 if (os_memcmp(c, tmp, p_len) != 0) {
292                         printf("GCM-AE mismatch (test case %d)\n", i);
293                         ret++;
294                 }
295
296                 if (os_memcmp(tag, t, sizeof(tag)) != 0) {
297                         printf("GCM-AE tag mismatch (test case %d)\n", i);
298                         ret++;
299                 }
300
301                 if (aes_128_gcm_ad(k, iv, iv_len, c, p_len, aad, aad_len, t,
302                                    tmp) < 0) {
303                         printf("GCM-AD failed (test case %d)\n", i);
304                         ret++;
305                         continue;
306                 }
307
308                 if (os_memcmp(p, tmp, p_len) != 0) {
309                         printf("GCM-AD mismatch (test case %d)\n", i);
310                         ret++;
311                 }
312         }
313
314         return ret;
315 }
316
317
318 /* OMAC1 AES-128 test vectors from
319  * http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/omac/omac-ad.pdf
320  * which are same as the examples from NIST SP800-38B
321  * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf
322  */
323
324 struct omac1_test_vector {
325         u8 k[16];
326         u8 msg[64];
327         int msg_len;
328         u8 tag[16];
329 };
330
331 static struct omac1_test_vector test_vectors[] =
332 {
333         {
334                 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
335                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
336                 { },
337                 0,
338                 { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
339                   0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 }
340         },
341         {
342                 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
343                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
344                 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
345                   0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
346                 16,
347                 { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
348                   0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }
349         },
350         {
351                 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
352                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
353                 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
354                   0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
355                   0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
356                   0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
357                   0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 },
358                 40,
359                 { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
360                   0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }
361         },
362         {
363                 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
364                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
365                 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
366                   0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
367                   0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
368                   0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
369                   0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
370                   0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
371                   0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
372                   0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
373                 64,
374                 { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
375                   0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe }
376         },
377 };
378
379
380 int main(int argc, char *argv[])
381 {
382         u8 kek[] = {
383                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
384                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
385         };
386         u8 plain[] = {
387                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
388                 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
389         };
390         u8 crypt[] = {
391                 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
392                 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
393                 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
394         };
395         u8 result[24];
396         int ret = 0;
397         unsigned int i;
398         struct omac1_test_vector *tv;
399
400         if (aes_wrap(kek, 2, plain, result)) {
401                 printf("AES-WRAP-128-128 reported failure\n");
402                 ret++;
403         }
404         if (memcmp(result, crypt, 24) != 0) {
405                 printf("AES-WRAP-128-128 failed\n");
406                 ret++;
407         }
408         if (aes_unwrap(kek, 2, crypt, result)) {
409                 printf("AES-UNWRAP-128-128 reported failure\n");
410                 ret++;
411         }
412         if (memcmp(result, plain, 16) != 0) {
413                 printf("AES-UNWRAP-128-128 failed\n");
414                 ret++;
415                 for (i = 0; i < 16; i++)
416                         printf(" %02x", result[i]);
417                 printf("\n");
418         }
419
420         test_aes_perf();
421
422         for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) {
423                 tv = &test_vectors[i];
424                 if (omac1_aes_128(tv->k, tv->msg, tv->msg_len, result) ||
425                     memcmp(result, tv->tag, 16) != 0) {
426                         printf("OMAC1-AES-128 test vector %d failed\n", i);
427                         ret++;
428                 }
429
430                 if (tv->msg_len > 1) {
431                         const u8 *addr[2];
432                         size_t len[2];
433
434                         addr[0] = tv->msg;
435                         len[0] = 1;
436                         addr[1] = tv->msg + 1;
437                         len[1] = tv->msg_len - 1;
438
439                         if (omac1_aes_128_vector(tv->k, 2, addr, len,
440                                                  result) ||
441                             memcmp(result, tv->tag, 16) != 0) {
442                                 printf("OMAC1-AES-128(vector) test vector %d "
443                                        "failed\n", i);
444                                 ret++;
445                         }
446                 }
447         }
448
449         ret += test_eax();
450
451         ret += test_cbc();
452
453         ret += test_gcm();
454
455         if (ret)
456                 printf("FAILED!\n");
457
458         return ret;
459 }