]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa_supplicant/aes_wrap.c
This commit was generated by cvs2svn to compensate for changes in r149749,
[FreeBSD/FreeBSD.git] / contrib / wpa_supplicant / aes_wrap.c
1 /*
2  * AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
3  * One-Key CBC MAC (OMAC1) hash with AES-128
4  * AES-128 CTR mode encryption
5  * AES-128 EAX mode encryption/decryption
6  * AES-128 CBC
7  * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  * Alternatively, this software may be distributed under the terms of BSD
14  * license.
15  *
16  * See README and COPYING for more details.
17  */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include "common.h"
23 #include "aes_wrap.h"
24
25 #ifdef EAP_TLS_FUNCS
26
27 #include <openssl/aes.h>
28
29 #else /* EAP_TLS_FUNCS */
30
31 #include "aes.c"
32
33 struct aes_key_st {
34         u32 rk[44];
35 };
36 typedef struct aes_key_st AES_KEY;
37
38 #define AES_set_encrypt_key(userKey, bits, key) \
39         rijndaelKeySetupEnc((key)->rk, (userKey))
40 #define AES_set_decrypt_key(userKey, bits, key) \
41         rijndaelKeySetupDec((key)->rk, (userKey))
42 #define AES_encrypt(in, out, key) \
43         rijndaelEncrypt((key)->rk, in, out)
44 #define AES_decrypt(in, out, key) \
45         rijndaelDecrypt((key)->rk, in, out)
46
47 #endif /* EAP_TLS_FUNCS */
48
49
50 /*
51  * @kek: key encryption key (KEK)
52  * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
53  * @plain: plaintext key to be wrapped, n * 64 bit
54  * @cipher: wrapped key, (n + 1) * 64 bit
55  */
56 void aes_wrap(u8 *kek, int n, u8 *plain, u8 *cipher)
57 {
58         u8 *a, *r, b[16];
59         int i, j;
60         AES_KEY key;
61
62         a = cipher;
63         r = cipher + 8;
64
65         /* 1) Initialize variables. */
66         memset(a, 0xa6, 8);
67         memcpy(r, plain, 8 * n);
68
69         AES_set_encrypt_key(kek, 128, &key);
70
71         /* 2) Calculate intermediate values.
72          * For j = 0 to 5
73          *     For i=1 to n
74          *         B = AES(K, A | R[i])
75          *         A = MSB(64, B) ^ t where t = (n*j)+i
76          *         R[i] = LSB(64, B)
77          */
78         for (j = 0; j <= 5; j++) {
79                 r = cipher + 8;
80                 for (i = 1; i <= n; i++) {
81                         memcpy(b, a, 8);
82                         memcpy(b + 8, r, 8);
83                         AES_encrypt(b, b, &key);
84                         memcpy(a, b, 8);
85                         a[7] ^= n * j + i;
86                         memcpy(r, b + 8, 8);
87                         r += 8;
88                 }
89         }
90
91         /* 3) Output the results.
92          *
93          * These are already in @cipher due to the location of temporary
94          * variables.
95          */
96 }
97
98
99 /*
100  * @kek: key encryption key (KEK)
101  * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
102  * @cipher: wrapped key to be unwrapped, (n + 1) * 64 bit
103  * @plain: plaintext key, n * 64 bit
104  */
105 int aes_unwrap(u8 *kek, int n, u8 *cipher, u8 *plain)
106 {
107         u8 a[8], *r, b[16];
108         int i, j;
109         AES_KEY key;
110
111         /* 1) Initialize variables. */
112         memcpy(a, cipher, 8);
113         r = plain;
114         memcpy(r, cipher + 8, 8 * n);
115
116         AES_set_decrypt_key(kek, 128, &key);
117
118         /* 2) Compute intermediate values.
119          * For j = 5 to 0
120          *     For i = n to 1
121          *         B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
122          *         A = MSB(64, B)
123          *         R[i] = LSB(64, B)
124          */
125         for (j = 5; j >= 0; j--) {
126                 r = plain + (n - 1) * 8;
127                 for (i = n; i >= 1; i--) {
128                         memcpy(b, a, 8);
129                         b[7] ^= n * j + i;
130
131                         memcpy(b + 8, r, 8);
132                         AES_decrypt(b, b, &key);
133                         memcpy(a, b, 8);
134                         memcpy(r, b + 8, 8);
135                         r -= 8;
136                 }
137         }
138
139         /* 3) Output results.
140          *
141          * These are already in @plain due to the location of temporary
142          * variables. Just verify that the IV matches with the expected value.
143          */
144         for (i = 0; i < 8; i++) {
145                 if (a[i] != 0xa6)
146                         return -1;
147         }
148
149         return 0;
150 }
151
152
153 #define BLOCK_SIZE 16
154
155 static void gf_mulx(u8 *pad)
156 {
157         int i, carry;
158
159         carry = pad[0] & 0x80;
160         for (i = 0; i < BLOCK_SIZE - 1; i++)
161                 pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
162         pad[BLOCK_SIZE - 1] <<= 1;
163         if (carry)
164                 pad[BLOCK_SIZE - 1] ^= 0x87;
165 }
166
167
168 void omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
169 {
170         AES_KEY akey;
171         u8 cbc[BLOCK_SIZE], pad[BLOCK_SIZE];
172         const u8 *pos = data;
173         int i;
174         size_t left = data_len;
175
176         AES_set_encrypt_key(key, 128, &akey);
177         memset(cbc, 0, BLOCK_SIZE);
178
179         while (left >= BLOCK_SIZE) {
180                 for (i = 0; i < BLOCK_SIZE; i++)
181                         cbc[i] ^= *pos++;
182                 if (left > BLOCK_SIZE)
183                         AES_encrypt(cbc, cbc, &akey);
184                 left -= BLOCK_SIZE;
185         }
186
187         memset(pad, 0, BLOCK_SIZE);
188         AES_encrypt(pad, pad, &akey);
189         gf_mulx(pad);
190
191         if (left || data_len == 0) {
192                 for (i = 0; i < left; i++)
193                         cbc[i] ^= *pos++;
194                 cbc[left] ^= 0x80;
195                 gf_mulx(pad);
196         }
197
198         for (i = 0; i < BLOCK_SIZE; i++)
199                 pad[i] ^= cbc[i];
200         AES_encrypt(pad, mac, &akey);
201 }
202
203
204 void aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out)
205 {
206         AES_KEY akey;
207         AES_set_encrypt_key(key, 128, &akey);
208         AES_encrypt(in, out, &akey);
209 }
210
211
212 void aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
213                          u8 *data, size_t data_len)
214 {
215         AES_KEY akey;
216         size_t len, left = data_len;
217         int i;
218         u8 *pos = data;
219         u8 counter[BLOCK_SIZE], buf[BLOCK_SIZE];
220
221         AES_set_encrypt_key(key, 128, &akey);
222         memcpy(counter, nonce, BLOCK_SIZE);
223
224         while (left > 0) {
225                 AES_encrypt(counter, buf, &akey);
226
227                 len = (left < BLOCK_SIZE) ? left : BLOCK_SIZE;
228                 for (i = 0; i < len; i++)
229                         pos[i] ^= buf[i];
230                 pos += len;
231                 left -= len;
232
233                 for (i = BLOCK_SIZE - 1; i >= 0; i--) {
234                         counter[i]++;
235                         if (counter[i])
236                                 break;
237                 }
238         }
239 }
240
241
242 int aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
243                         const u8 *hdr, size_t hdr_len,
244                         u8 *data, size_t data_len, u8 *tag)
245 {
246         u8 *buf;
247         size_t buf_len;
248         u8 nonce_mac[BLOCK_SIZE], hdr_mac[BLOCK_SIZE], data_mac[BLOCK_SIZE];
249         int i;
250
251         if (nonce_len > data_len)
252                 buf_len = nonce_len;
253         else
254                 buf_len = data_len;
255         if (hdr_len > buf_len)
256                 buf_len = hdr_len;
257         buf_len += 16;
258
259         buf = malloc(buf_len);
260         if (buf == NULL)
261                 return -1;
262
263         memset(buf, 0, 15);
264
265         buf[15] = 0;
266         memcpy(buf + 16, nonce, nonce_len);
267         omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac);
268
269         buf[15] = 1;
270         memcpy(buf + 16, hdr, hdr_len);
271         omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac);
272
273         aes_128_ctr_encrypt(key, nonce_mac, data, data_len);
274         buf[15] = 2;
275         memcpy(buf + 16, data, data_len);
276         omac1_aes_128(key, buf, 16 + data_len, data_mac);
277
278         free(buf);
279
280         for (i = 0; i < BLOCK_SIZE; i++)
281                 tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i];
282
283         return 0;
284 }
285
286
287 int aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
288                         const u8 *hdr, size_t hdr_len,
289                         u8 *data, size_t data_len, const u8 *tag)
290 {
291         u8 *buf;
292         size_t buf_len;
293         u8 nonce_mac[BLOCK_SIZE], hdr_mac[BLOCK_SIZE], data_mac[BLOCK_SIZE];
294         int i;
295
296         if (nonce_len > data_len)
297                 buf_len = nonce_len;
298         else
299                 buf_len = data_len;
300         if (hdr_len > buf_len)
301                 buf_len = hdr_len;
302         buf_len += 16;
303
304         buf = malloc(buf_len);
305         if (buf == NULL)
306                 return -1;
307
308         memset(buf, 0, 15);
309
310         buf[15] = 0;
311         memcpy(buf + 16, nonce, nonce_len);
312         omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac);
313
314         buf[15] = 1;
315         memcpy(buf + 16, hdr, hdr_len);
316         omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac);
317
318         buf[15] = 2;
319         memcpy(buf + 16, data, data_len);
320         omac1_aes_128(key, buf, 16 + data_len, data_mac);
321
322         free(buf);
323
324         for (i = 0; i < BLOCK_SIZE; i++) {
325                 if (tag[i] != (nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]))
326                         return -2;
327         }
328
329         aes_128_ctr_encrypt(key, nonce_mac, data, data_len);
330
331         return 0;
332 }
333
334
335 void aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data,
336                          size_t data_len)
337 {
338         AES_KEY akey;
339         u8 cbc[BLOCK_SIZE];
340         u8 *pos = data;
341         int i, j, blocks;
342
343         AES_set_encrypt_key(key, 128, &akey);
344         memcpy(cbc, iv, BLOCK_SIZE);
345
346         blocks = data_len / BLOCK_SIZE;
347         for (i = 0; i < blocks; i++) {
348                 for (j = 0; j < BLOCK_SIZE; j++)
349                         cbc[j] ^= pos[j];
350                 AES_encrypt(cbc, cbc, &akey);
351                 memcpy(pos, cbc, BLOCK_SIZE);
352                 pos += BLOCK_SIZE;
353         }
354 }
355
356
357 void aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
358                          size_t data_len)
359 {
360         AES_KEY akey;
361         u8 cbc[BLOCK_SIZE], tmp[BLOCK_SIZE];
362         u8 *pos = data;
363         int i, j, blocks;
364
365         AES_set_decrypt_key(key, 128, &akey);
366         memcpy(cbc, iv, BLOCK_SIZE);
367
368         blocks = data_len / BLOCK_SIZE;
369         for (i = 0; i < blocks; i++) {
370                 memcpy(tmp, pos, BLOCK_SIZE);
371                 AES_decrypt(pos, pos, &akey);
372                 for (j = 0; j < BLOCK_SIZE; j++)
373                         pos[j] ^= cbc[j];
374                 memcpy(cbc, tmp, BLOCK_SIZE);
375                 pos += BLOCK_SIZE;
376         }
377 }
378
379
380 #ifdef TEST_MAIN
381
382 #ifdef __i386__
383 #define rdtscll(val) \
384      __asm__ __volatile__("rdtsc" : "=A" (val))
385
386 static void test_aes_perf(void)
387 {
388         const int num_iters = 10;
389         int i;
390         unsigned int start, end;
391         AES_KEY akey;
392         u8 key[16], pt[16], ct[16];
393
394         printf("keySetupEnc:");
395         for (i = 0; i < num_iters; i++) {
396                 rdtscll(start);
397                 AES_set_encrypt_key(key, 128, &akey);
398                 rdtscll(end);
399                 printf(" %d", end - start);
400         }
401         printf("\n");
402
403         printf("Encrypt:");
404         for (i = 0; i < num_iters; i++) {
405                 rdtscll(start);
406                 AES_encrypt(pt, ct, &akey);
407                 rdtscll(end);
408                 printf(" %d", end - start);
409         }
410         printf("\n");
411 }
412 #endif /* __i386__ */
413
414
415 static int test_eax(void)
416 {
417         u8 msg[] = { 0xF7, 0xFB };
418         u8 key[] = { 0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B,
419                      0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4 };
420         u8 nonce[] = { 0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84,
421                        0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD };
422         u8 hdr[] = { 0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA };
423         u8 cipher[] = { 0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D,
424                         0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79,
425                         0x67, 0xE5 };
426         u8 data[sizeof(msg)], tag[BLOCK_SIZE];
427
428         memcpy(data, msg, sizeof(msg));
429         if (aes_128_eax_encrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
430                                 data, sizeof(data), tag)) {
431                 printf("AES-128 EAX mode encryption failed\n");
432                 return 1;
433         }
434         if (memcmp(data, cipher, sizeof(data)) != 0) {
435                 printf("AES-128 EAX mode encryption returned invalid cipher "
436                        "text\n");
437                 return 1;
438         }
439         if (memcmp(tag, cipher + sizeof(data), BLOCK_SIZE) != 0) {
440                 printf("AES-128 EAX mode encryption returned invalid tag\n");
441                 return 1;
442         }
443
444         if (aes_128_eax_decrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
445                                 data, sizeof(data), tag)) {
446                 printf("AES-128 EAX mode decryption failed\n");
447                 return 1;
448         }
449         if (memcmp(data, msg, sizeof(data)) != 0) {
450                 printf("AES-128 EAX mode decryption returned invalid plain "
451                        "text\n");
452                 return 1;
453         }
454
455         return 0;
456 }
457
458
459 static int test_cbc(void)
460 {
461         struct cbc_test_vector {
462                 u8 key[16];
463                 u8 iv[16];
464                 u8 plain[32];
465                 u8 cipher[32];
466                 size_t len;
467         } vectors[] = {
468                 {
469                         { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
470                           0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
471                         { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
472                           0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
473                         "Single block msg",
474                         { 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8,
475                           0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a },
476                         16
477                 },
478                 {
479                         { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
480                           0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
481                         { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
482                           0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
483                         { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
484                           0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
485                           0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
486                           0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
487                         { 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
488                           0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
489                           0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
490                           0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
491                         32
492                 }
493         };
494         int i, ret = 0;
495         u8 *buf;
496
497         for (i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
498                 struct cbc_test_vector *tv = &vectors[i];
499                 buf = malloc(tv->len);
500                 if (buf == NULL) {
501                         ret++;
502                         break;
503                 }
504                 memcpy(buf, tv->plain, tv->len);
505                 aes_128_cbc_encrypt(tv->key, tv->iv, buf, tv->len);
506                 if (memcmp(buf, tv->cipher, tv->len) != 0) {
507                         printf("AES-CBC encrypt %d failed\n", i);
508                         ret++;
509                 }
510                 memcpy(buf, tv->cipher, tv->len);
511                 aes_128_cbc_decrypt(tv->key, tv->iv, buf, tv->len);
512                 if (memcmp(buf, tv->plain, tv->len) != 0) {
513                         printf("AES-CBC decrypt %d failed\n", i);
514                         ret++;
515                 }
516                 free(buf);
517         }
518
519         return ret;
520 }
521
522
523 /* OMAC1 AES-128 test vectors from
524  * http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/omac/omac-ad.pdf
525  */
526
527 struct omac1_test_vector {
528         u8 k[16];
529         u8 msg[64];
530         int msg_len;
531         u8 tag[16];
532 };
533
534 static struct omac1_test_vector test_vectors[] =
535 {
536         {
537                 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
538                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
539                 { },
540                 0,
541                 { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
542                   0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 }
543         },
544         {
545                 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
546                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
547                 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
548                   0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
549                 16,
550                 { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
551                   0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }
552         },
553         {
554                 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
555                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
556                 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
557                   0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
558                   0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
559                   0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
560                   0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 },
561                 40,
562                 { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
563                   0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }
564         },
565         {
566                 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
567                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
568                 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
569                   0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
570                   0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
571                   0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
572                   0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
573                   0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
574                   0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
575                   0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
576                 64,
577                 { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
578                   0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe }
579         },
580 };
581
582
583 int main(int argc, char *argv[])
584 {
585         u8 kek[] = {
586                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
587                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
588         };
589         u8 plain[] = {
590                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
591                 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
592         };
593         u8 crypt[] = {
594                 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
595                 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
596                 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
597         };
598         u8 result[24];
599         int ret = 0, i;
600         struct omac1_test_vector *tv;
601
602         aes_wrap(kek, 2, plain, result);
603         if (memcmp(result, crypt, 24) != 0) {
604                 printf("AES-WRAP-128-128 failed\n");
605                 ret++;
606         }
607         if (aes_unwrap(kek, 2, crypt, result)) {
608                 printf("AES-UNWRAP-128-128 reported failure\n");
609                 ret++;
610         }
611         if (memcmp(result, plain, 16) != 0) {
612                 int i;
613                 printf("AES-UNWRAP-128-128 failed\n");
614                 ret++;
615                 for (i = 0; i < 16; i++)
616                         printf(" %02x", result[i]);
617                 printf("\n");
618         }
619
620 #ifdef __i386__
621         test_aes_perf();
622 #endif /* __i386__ */
623
624         for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) {
625                 tv = &test_vectors[i];
626                 omac1_aes_128(tv->k, tv->msg, tv->msg_len, result);
627                 if (memcmp(result, tv->tag, 16) != 0) {
628                         printf("OMAC1-AES-128 test vector %d failed\n", i);
629                         ret++;
630                 }
631         }
632
633         ret += test_eax();
634
635         ret += test_cbc();
636
637         if (ret)
638                 printf("FAILED!\n");
639
640         return ret;
641 }
642 #endif /* TEST_MAIN */