Re-enable hardware UDP/TCP checksum calculation with pseudo header on
[dragonfly/port-amd64.git] / contrib / wpa_supplicant-0.4.9 / aes_wrap.c
bloba5925ca2ec47b611fd4a33e55d8c641c744e6955
1 /*
2 * AES-based functions
4 * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
5 * - One-Key CBC MAC (OMAC1) hash with AES-128
6 * - AES-128 CTR mode encryption
7 * - AES-128 EAX mode encryption/decryption
8 * - AES-128 CBC
10 * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
16 * Alternatively, this software may be distributed under the terms of BSD
17 * license.
19 * See README and COPYING for more details.
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include "common.h"
26 #include "aes_wrap.h"
27 #include "crypto.h"
29 #ifndef EAP_TLS_FUNCS
30 #include "aes.c"
31 #endif /* EAP_TLS_FUNCS */
34 /**
35 * aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
36 * @kek: Key encryption key (KEK)
37 * @n: Length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
38 * @plain: Plaintext key to be wrapped, n * 64 bit
39 * @cipher: Wrapped key, (n + 1) * 64 bit
40 * Returns: 0 on success, -1 on failure
42 int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
44 u8 *a, *r, b[16];
45 int i, j;
46 void *ctx;
48 a = cipher;
49 r = cipher + 8;
51 /* 1) Initialize variables. */
52 memset(a, 0xa6, 8);
53 memcpy(r, plain, 8 * n);
55 ctx = aes_encrypt_init(kek, 16);
56 if (ctx == NULL)
57 return -1;
59 /* 2) Calculate intermediate values.
60 * For j = 0 to 5
61 * For i=1 to n
62 * B = AES(K, A | R[i])
63 * A = MSB(64, B) ^ t where t = (n*j)+i
64 * R[i] = LSB(64, B)
66 for (j = 0; j <= 5; j++) {
67 r = cipher + 8;
68 for (i = 1; i <= n; i++) {
69 memcpy(b, a, 8);
70 memcpy(b + 8, r, 8);
71 aes_encrypt(ctx, b, b);
72 memcpy(a, b, 8);
73 a[7] ^= n * j + i;
74 memcpy(r, b + 8, 8);
75 r += 8;
78 aes_encrypt_deinit(ctx);
80 /* 3) Output the results.
82 * These are already in @cipher due to the location of temporary
83 * variables.
86 return 0;
90 /**
91 * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
92 * @kek: Key encryption key (KEK)
93 * @n: Length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
94 * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bit
95 * @plain: Plaintext key, n * 64 bit
96 * Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
98 int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain)
100 u8 a[8], *r, b[16];
101 int i, j;
102 void *ctx;
104 /* 1) Initialize variables. */
105 memcpy(a, cipher, 8);
106 r = plain;
107 memcpy(r, cipher + 8, 8 * n);
109 ctx = aes_decrypt_init(kek, 16);
110 if (ctx == NULL)
111 return -1;
113 /* 2) Compute intermediate values.
114 * For j = 5 to 0
115 * For i = n to 1
116 * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
117 * A = MSB(64, B)
118 * R[i] = LSB(64, B)
120 for (j = 5; j >= 0; j--) {
121 r = plain + (n - 1) * 8;
122 for (i = n; i >= 1; i--) {
123 memcpy(b, a, 8);
124 b[7] ^= n * j + i;
126 memcpy(b + 8, r, 8);
127 aes_decrypt(ctx, b, b);
128 memcpy(a, b, 8);
129 memcpy(r, b + 8, 8);
130 r -= 8;
133 aes_decrypt_deinit(ctx);
135 /* 3) Output results.
137 * These are already in @plain due to the location of temporary
138 * variables. Just verify that the IV matches with the expected value.
140 for (i = 0; i < 8; i++) {
141 if (a[i] != 0xa6)
142 return -1;
145 return 0;
149 #define BLOCK_SIZE 16
151 static void gf_mulx(u8 *pad)
153 int i, carry;
155 carry = pad[0] & 0x80;
156 for (i = 0; i < BLOCK_SIZE - 1; i++)
157 pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
158 pad[BLOCK_SIZE - 1] <<= 1;
159 if (carry)
160 pad[BLOCK_SIZE - 1] ^= 0x87;
165 * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128
166 * @key: Key for the hash operation
167 * @data: Data buffer for which a MAC is determined
168 * @data: Length of data buffer in bytes
169 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
170 * Returns: 0 on success, -1 on failure
172 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
174 void *ctx;
175 u8 cbc[BLOCK_SIZE], pad[BLOCK_SIZE];
176 const u8 *pos = data;
177 int i;
178 size_t left = data_len;
180 ctx = aes_encrypt_init(key, 16);
181 if (ctx == NULL)
182 return -1;
183 memset(cbc, 0, BLOCK_SIZE);
185 while (left >= BLOCK_SIZE) {
186 for (i = 0; i < BLOCK_SIZE; i++)
187 cbc[i] ^= *pos++;
188 if (left > BLOCK_SIZE)
189 aes_encrypt(ctx, cbc, cbc);
190 left -= BLOCK_SIZE;
193 memset(pad, 0, BLOCK_SIZE);
194 aes_encrypt(ctx, pad, pad);
195 gf_mulx(pad);
197 if (left || data_len == 0) {
198 for (i = 0; i < left; i++)
199 cbc[i] ^= *pos++;
200 cbc[left] ^= 0x80;
201 gf_mulx(pad);
204 for (i = 0; i < BLOCK_SIZE; i++)
205 pad[i] ^= cbc[i];
206 aes_encrypt(ctx, pad, mac);
207 aes_encrypt_deinit(ctx);
208 return 0;
213 * aes_128_encrypt_block - Perform one AES 128-bit block operation
214 * @key: Key for AES
215 * @in: Input data (16 bytes)
216 * @out: Output of the AES block operation (16 bytes)
217 * Returns: 0 on success, -1 on failure
219 int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out)
221 void *ctx;
222 ctx = aes_encrypt_init(key, 16);
223 if (ctx == NULL)
224 return -1;
225 aes_encrypt(ctx, in, out);
226 aes_encrypt_deinit(ctx);
227 return 0;
232 * aes_128_ctr_encrypt - AES-128 CTR mode encryption
233 * @key: Key for encryption (16 bytes)
234 * @nonce: Nonce for counter mode (16 bytes)
235 * @data: Data to encrypt in-place
236 * @data_len: Length of data in bytes
237 * Returns: 0 on success, -1 on failure
239 int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
240 u8 *data, size_t data_len)
242 void *ctx;
243 size_t len, left = data_len;
244 int i;
245 u8 *pos = data;
246 u8 counter[BLOCK_SIZE], buf[BLOCK_SIZE];
248 ctx = aes_encrypt_init(key, 16);
249 if (ctx == NULL)
250 return -1;
251 memcpy(counter, nonce, BLOCK_SIZE);
253 while (left > 0) {
254 aes_encrypt(ctx, counter, buf);
256 len = (left < BLOCK_SIZE) ? left : BLOCK_SIZE;
257 for (i = 0; i < len; i++)
258 pos[i] ^= buf[i];
259 pos += len;
260 left -= len;
262 for (i = BLOCK_SIZE - 1; i >= 0; i--) {
263 counter[i]++;
264 if (counter[i])
265 break;
268 aes_encrypt_deinit(ctx);
269 return 0;
274 * aes_128_eax_encrypt - AES-128 EAX mode encryption
275 * @key: Key for encryption (16 bytes)
276 * @nonce: Nonce for counter mode
277 * @nonce_len: Nonce length in bytes
278 * @hdr: Header data to be authenticity protected
279 * @hdr_len: Length of the header data bytes
280 * @data: Data to encrypt in-place
281 * @data_len: Length of data in bytes
282 * @tag: 16-byte tag value
283 * Returns: 0 on success, -1 on failure
285 int aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
286 const u8 *hdr, size_t hdr_len,
287 u8 *data, size_t data_len, u8 *tag)
289 u8 *buf;
290 size_t buf_len;
291 u8 nonce_mac[BLOCK_SIZE], hdr_mac[BLOCK_SIZE], data_mac[BLOCK_SIZE];
292 int i;
294 if (nonce_len > data_len)
295 buf_len = nonce_len;
296 else
297 buf_len = data_len;
298 if (hdr_len > buf_len)
299 buf_len = hdr_len;
300 buf_len += 16;
302 buf = malloc(buf_len);
303 if (buf == NULL)
304 return -1;
306 memset(buf, 0, 15);
308 buf[15] = 0;
309 memcpy(buf + 16, nonce, nonce_len);
310 omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac);
312 buf[15] = 1;
313 memcpy(buf + 16, hdr, hdr_len);
314 omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac);
316 aes_128_ctr_encrypt(key, nonce_mac, data, data_len);
317 buf[15] = 2;
318 memcpy(buf + 16, data, data_len);
319 omac1_aes_128(key, buf, 16 + data_len, data_mac);
321 free(buf);
323 for (i = 0; i < BLOCK_SIZE; i++)
324 tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i];
326 return 0;
331 * aes_128_eax_decrypt - AES-128 EAX mode decryption
332 * @key: Key for decryption (16 bytes)
333 * @nonce: Nonce for counter mode
334 * @nonce_len: Nonce length in bytes
335 * @hdr: Header data to be authenticity protected
336 * @hdr_len: Length of the header data bytes
337 * @data: Data to encrypt in-place
338 * @data_len: Length of data in bytes
339 * @tag: 16-byte tag value
340 * Returns: 0 on success, -1 on failure, -2 if tag does not match
342 int aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
343 const u8 *hdr, size_t hdr_len,
344 u8 *data, size_t data_len, const u8 *tag)
346 u8 *buf;
347 size_t buf_len;
348 u8 nonce_mac[BLOCK_SIZE], hdr_mac[BLOCK_SIZE], data_mac[BLOCK_SIZE];
349 int i;
351 if (nonce_len > data_len)
352 buf_len = nonce_len;
353 else
354 buf_len = data_len;
355 if (hdr_len > buf_len)
356 buf_len = hdr_len;
357 buf_len += 16;
359 buf = malloc(buf_len);
360 if (buf == NULL)
361 return -1;
363 memset(buf, 0, 15);
365 buf[15] = 0;
366 memcpy(buf + 16, nonce, nonce_len);
367 omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac);
369 buf[15] = 1;
370 memcpy(buf + 16, hdr, hdr_len);
371 omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac);
373 buf[15] = 2;
374 memcpy(buf + 16, data, data_len);
375 omac1_aes_128(key, buf, 16 + data_len, data_mac);
377 free(buf);
379 for (i = 0; i < BLOCK_SIZE; i++) {
380 if (tag[i] != (nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]))
381 return -2;
384 aes_128_ctr_encrypt(key, nonce_mac, data, data_len);
386 return 0;
391 * aes_128_cbc_encrypt - AES-128 CBC encryption
392 * @key: Encryption key
393 * @iv: Encryption IV for CBC mode (16 bytes)
394 * @data: Data to encrypt in-place
395 * @data_len: Length of data in bytes (must be divisible by 16)
396 * Returns: 0 on success, -1 on failure
398 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
400 void *ctx;
401 u8 cbc[BLOCK_SIZE];
402 u8 *pos = data;
403 int i, j, blocks;
405 ctx = aes_encrypt_init(key, 16);
406 if (ctx == NULL)
407 return -1;
408 memcpy(cbc, iv, BLOCK_SIZE);
410 blocks = data_len / BLOCK_SIZE;
411 for (i = 0; i < blocks; i++) {
412 for (j = 0; j < BLOCK_SIZE; j++)
413 cbc[j] ^= pos[j];
414 aes_encrypt(ctx, cbc, cbc);
415 memcpy(pos, cbc, BLOCK_SIZE);
416 pos += BLOCK_SIZE;
418 aes_encrypt_deinit(ctx);
419 return 0;
424 * aes_128_cbc_decrypt - AES-128 CBC decryption
425 * @key: Decryption key
426 * @iv: Decryption IV for CBC mode (16 bytes)
427 * @data: Data to decrypt in-place
428 * @data_len: Length of data in bytes (must be divisible by 16)
429 * Returns: 0 on success, -1 on failure
431 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
433 void *ctx;
434 u8 cbc[BLOCK_SIZE], tmp[BLOCK_SIZE];
435 u8 *pos = data;
436 int i, j, blocks;
438 ctx = aes_decrypt_init(key, 16);
439 if (ctx == NULL)
440 return -1;
441 memcpy(cbc, iv, BLOCK_SIZE);
443 blocks = data_len / BLOCK_SIZE;
444 for (i = 0; i < blocks; i++) {
445 memcpy(tmp, pos, BLOCK_SIZE);
446 aes_decrypt(ctx, pos, pos);
447 for (j = 0; j < BLOCK_SIZE; j++)
448 pos[j] ^= cbc[j];
449 memcpy(cbc, tmp, BLOCK_SIZE);
450 pos += BLOCK_SIZE;
452 aes_decrypt_deinit(ctx);
453 return 0;
457 #ifdef TEST_MAIN
459 #ifdef __i386__
460 #define rdtscll(val) \
461 __asm__ __volatile__("rdtsc" : "=A" (val))
463 static void test_aes_perf(void)
465 const int num_iters = 10;
466 int i;
467 unsigned int start, end;
468 u8 key[16], pt[16], ct[16];
469 void *ctx;
471 printf("keySetupEnc:");
472 for (i = 0; i < num_iters; i++) {
473 rdtscll(start);
474 ctx = aes_encrypt_init(key, 16);
475 rdtscll(end);
476 aes_encrypt_deinit(ctx);
477 printf(" %d", end - start);
479 printf("\n");
481 printf("Encrypt:");
482 ctx = aes_encrypt_init(key, 16);
483 for (i = 0; i < num_iters; i++) {
484 rdtscll(start);
485 aes_encrypt(ctx, pt, ct);
486 rdtscll(end);
487 printf(" %d", end - start);
489 aes_encrypt_deinit(ctx);
490 printf("\n");
492 #endif /* __i386__ */
495 static int test_eax(void)
497 u8 msg[] = { 0xF7, 0xFB };
498 u8 key[] = { 0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B,
499 0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4 };
500 u8 nonce[] = { 0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84,
501 0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD };
502 u8 hdr[] = { 0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA };
503 u8 cipher[] = { 0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D,
504 0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79,
505 0x67, 0xE5 };
506 u8 data[sizeof(msg)], tag[BLOCK_SIZE];
508 memcpy(data, msg, sizeof(msg));
509 if (aes_128_eax_encrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
510 data, sizeof(data), tag)) {
511 printf("AES-128 EAX mode encryption failed\n");
512 return 1;
514 if (memcmp(data, cipher, sizeof(data)) != 0) {
515 printf("AES-128 EAX mode encryption returned invalid cipher "
516 "text\n");
517 return 1;
519 if (memcmp(tag, cipher + sizeof(data), BLOCK_SIZE) != 0) {
520 printf("AES-128 EAX mode encryption returned invalid tag\n");
521 return 1;
524 if (aes_128_eax_decrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
525 data, sizeof(data), tag)) {
526 printf("AES-128 EAX mode decryption failed\n");
527 return 1;
529 if (memcmp(data, msg, sizeof(data)) != 0) {
530 printf("AES-128 EAX mode decryption returned invalid plain "
531 "text\n");
532 return 1;
535 return 0;
539 static int test_cbc(void)
541 struct cbc_test_vector {
542 u8 key[16];
543 u8 iv[16];
544 u8 plain[32];
545 u8 cipher[32];
546 size_t len;
547 } vectors[] = {
549 { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
550 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
551 { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
552 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
553 "Single block msg",
554 { 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8,
555 0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a },
559 { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
560 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
561 { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
562 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
563 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
564 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
565 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
566 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
567 { 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
568 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
569 0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
570 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
574 int i, ret = 0;
575 u8 *buf;
577 for (i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
578 struct cbc_test_vector *tv = &vectors[i];
579 buf = malloc(tv->len);
580 if (buf == NULL) {
581 ret++;
582 break;
584 memcpy(buf, tv->plain, tv->len);
585 aes_128_cbc_encrypt(tv->key, tv->iv, buf, tv->len);
586 if (memcmp(buf, tv->cipher, tv->len) != 0) {
587 printf("AES-CBC encrypt %d failed\n", i);
588 ret++;
590 memcpy(buf, tv->cipher, tv->len);
591 aes_128_cbc_decrypt(tv->key, tv->iv, buf, tv->len);
592 if (memcmp(buf, tv->plain, tv->len) != 0) {
593 printf("AES-CBC decrypt %d failed\n", i);
594 ret++;
596 free(buf);
599 return ret;
603 /* OMAC1 AES-128 test vectors from
604 * http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/omac/omac-ad.pdf
607 struct omac1_test_vector {
608 u8 k[16];
609 u8 msg[64];
610 int msg_len;
611 u8 tag[16];
614 static struct omac1_test_vector test_vectors[] =
617 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
618 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
619 { },
621 { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
622 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 }
625 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
626 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
627 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
628 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
630 { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
631 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }
634 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
635 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
636 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
637 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
638 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
639 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
640 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 },
642 { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
643 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }
646 { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
647 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
648 { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
649 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
650 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
651 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
652 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
653 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
654 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
655 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
657 { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
658 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe }
663 int main(int argc, char *argv[])
665 u8 kek[] = {
666 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
667 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
669 u8 plain[] = {
670 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
671 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
673 u8 crypt[] = {
674 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
675 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
676 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
678 u8 result[24];
679 int ret = 0, i;
680 struct omac1_test_vector *tv;
682 if (aes_wrap(kek, 2, plain, result)) {
683 printf("AES-WRAP-128-128 reported failure\n");
684 ret++;
686 if (memcmp(result, crypt, 24) != 0) {
687 printf("AES-WRAP-128-128 failed\n");
688 ret++;
690 if (aes_unwrap(kek, 2, crypt, result)) {
691 printf("AES-UNWRAP-128-128 reported failure\n");
692 ret++;
694 if (memcmp(result, plain, 16) != 0) {
695 int i;
696 printf("AES-UNWRAP-128-128 failed\n");
697 ret++;
698 for (i = 0; i < 16; i++)
699 printf(" %02x", result[i]);
700 printf("\n");
703 #ifdef __i386__
704 test_aes_perf();
705 #endif /* __i386__ */
707 for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) {
708 tv = &test_vectors[i];
709 omac1_aes_128(tv->k, tv->msg, tv->msg_len, result);
710 if (memcmp(result, tv->tag, 16) != 0) {
711 printf("OMAC1-AES-128 test vector %d failed\n", i);
712 ret++;
716 ret += test_eax();
718 ret += test_cbc();
720 if (ret)
721 printf("FAILED!\n");
723 return ret;
725 #endif /* TEST_MAIN */