1/*
2 * Test program for AES
3 * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
16
17#include "common.h"
18#include "crypto.h"
19#include "aes_wrap.h"
20
21#define BLOCK_SIZE 16
22
23static void test_aes_perf(void)
24{
25#if 0 /* this did not seem to work with new compiler?! */
26#ifdef __i386__
27#define rdtscll(val) \
28     __asm__ __volatile__("rdtsc" : "=A" (val))
29	const int num_iters = 10;
30	int i;
31	unsigned int start, end;
32	u8 key[16], pt[16], ct[16];
33	void *ctx;
34
35	printf("keySetupEnc:");
36	for (i = 0; i < num_iters; i++) {
37		rdtscll(start);
38		ctx = aes_encrypt_init(key, 16);
39		rdtscll(end);
40		aes_encrypt_deinit(ctx);
41		printf(" %d", end - start);
42	}
43	printf("\n");
44
45	printf("Encrypt:");
46	ctx = aes_encrypt_init(key, 16);
47	for (i = 0; i < num_iters; i++) {
48		rdtscll(start);
49		aes_encrypt(ctx, pt, ct);
50		rdtscll(end);
51		printf(" %d", end - start);
52	}
53	aes_encrypt_deinit(ctx);
54	printf("\n");
55#endif /* __i386__ */
56#endif
57}
58
59
60static int test_eax(void)
61{
62	u8 msg[] = { 0xF7, 0xFB };
63	u8 key[] = { 0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B,
64		     0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4 };
65	u8 nonce[] = { 0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84,
66		       0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD };
67	u8 hdr[] = { 0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA };
68	u8 cipher[] = { 0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D,
69			0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79,
70			0x67, 0xE5 };
71	u8 data[sizeof(msg)], tag[BLOCK_SIZE];
72
73	memcpy(data, msg, sizeof(msg));
74	if (aes_128_eax_encrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
75				data, sizeof(data), tag)) {
76		printf("AES-128 EAX mode encryption failed\n");
77		return 1;
78	}
79	if (memcmp(data, cipher, sizeof(data)) != 0) {
80		printf("AES-128 EAX mode encryption returned invalid cipher "
81		       "text\n");
82		return 1;
83	}
84	if (memcmp(tag, cipher + sizeof(data), BLOCK_SIZE) != 0) {
85		printf("AES-128 EAX mode encryption returned invalid tag\n");
86		return 1;
87	}
88
89	if (aes_128_eax_decrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
90				data, sizeof(data), tag)) {
91		printf("AES-128 EAX mode decryption failed\n");
92		return 1;
93	}
94	if (memcmp(data, msg, sizeof(data)) != 0) {
95		printf("AES-128 EAX mode decryption returned invalid plain "
96		       "text\n");
97		return 1;
98	}
99
100	return 0;
101}
102
103
104static int test_cbc(void)
105{
106	struct cbc_test_vector {
107		u8 key[16];
108		u8 iv[16];
109		u8 plain[32];
110		u8 cipher[32];
111		size_t len;
112	} vectors[] = {
113		{
114			{ 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
115			  0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
116			{ 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
117			  0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
118			"Single block msg",
119			{ 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8,
120			  0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a },
121			16
122		},
123		{
124			{ 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
125			  0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
126			{ 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
127			  0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
128			{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
129			  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
130			  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
131			  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
132			{ 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
133			  0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
134			  0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
135			  0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
136			32
137		}
138	};
139	int ret = 0;
140	u8 *buf;
141	unsigned int i;
142
143	for (i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
144		struct cbc_test_vector *tv = &vectors[i];
145		buf = malloc(tv->len);
146		if (buf == NULL) {
147			ret++;
148			break;
149		}
150		memcpy(buf, tv->plain, tv->len);
151		aes_128_cbc_encrypt(tv->key, tv->iv, buf, tv->len);
152		if (memcmp(buf, tv->cipher, tv->len) != 0) {
153			printf("AES-CBC encrypt %d failed\n", i);
154			ret++;
155		}
156		memcpy(buf, tv->cipher, tv->len);
157		aes_128_cbc_decrypt(tv->key, tv->iv, buf, tv->len);
158		if (memcmp(buf, tv->plain, tv->len) != 0) {
159			printf("AES-CBC decrypt %d failed\n", i);
160			ret++;
161		}
162		free(buf);
163	}
164
165	return ret;
166}
167
168
169/* OMAC1 AES-128 test vectors from
170 * http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/omac/omac-ad.pdf
171 */
172
173struct omac1_test_vector {
174	u8 k[16];
175	u8 msg[64];
176	int msg_len;
177	u8 tag[16];
178};
179
180static struct omac1_test_vector test_vectors[] =
181{
182	{
183		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
184		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
185		{ },
186		0,
187		{ 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
188		  0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 }
189	},
190	{
191		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
192		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
193		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
194		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
195		16,
196		{ 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
197		  0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }
198	},
199	{
200		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
201		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
202		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
203		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
204		  0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
205		  0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
206		  0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 },
207		40,
208		{ 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
209		  0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }
210	},
211	{
212		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
213		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
214		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
215		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
216		  0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
217		  0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
218		  0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
219		  0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
220		  0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
221		  0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
222		64,
223		{ 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
224		  0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe }
225	},
226};
227
228
229int main(int argc, char *argv[])
230{
231	u8 kek[] = {
232		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
233		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
234	};
235	u8 plain[] = {
236		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
237		0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
238	};
239	u8 crypt[] = {
240		0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
241		0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
242		0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
243	};
244	u8 result[24];
245	int ret = 0;
246	unsigned int i;
247	struct omac1_test_vector *tv;
248
249	if (aes_wrap(kek, 2, plain, result)) {
250		printf("AES-WRAP-128-128 reported failure\n");
251		ret++;
252	}
253	if (memcmp(result, crypt, 24) != 0) {
254		printf("AES-WRAP-128-128 failed\n");
255		ret++;
256	}
257	if (aes_unwrap(kek, 2, crypt, result)) {
258		printf("AES-UNWRAP-128-128 reported failure\n");
259		ret++;
260	}
261	if (memcmp(result, plain, 16) != 0) {
262		int i;
263		printf("AES-UNWRAP-128-128 failed\n");
264		ret++;
265		for (i = 0; i < 16; i++)
266			printf(" %02x", result[i]);
267		printf("\n");
268	}
269
270	test_aes_perf();
271
272	for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) {
273		tv = &test_vectors[i];
274		omac1_aes_128(tv->k, tv->msg, tv->msg_len, result);
275		if (memcmp(result, tv->tag, 16) != 0) {
276			printf("OMAC1-AES-128 test vector %d failed\n", i);
277			ret++;
278		}
279
280		if (tv->msg_len > 1) {
281			const u8 *addr[2];
282			size_t len[2];
283
284			addr[0] = tv->msg;
285			len[0] = 1;
286			addr[1] = tv->msg + 1;
287			len[1] = tv->msg_len - 1;
288
289			omac1_aes_128_vector(tv->k, 2, addr, len, result);
290			if (memcmp(result, tv->tag, 16) != 0) {
291				printf("OMAC1-AES-128(vector) test vector %d "
292				       "failed\n", i);
293				ret++;
294			}
295		}
296	}
297
298	ret += test_eax();
299
300	ret += test_cbc();
301
302	if (ret)
303		printf("FAILED!\n");
304
305	return ret;
306}
307