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 * which are same as the examples from NIST SP800-38B
172 * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf
173 */
174
175struct omac1_test_vector {
176	u8 k[16];
177	u8 msg[64];
178	int msg_len;
179	u8 tag[16];
180};
181
182static struct omac1_test_vector test_vectors[] =
183{
184	{
185		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
186		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
187		{ },
188		0,
189		{ 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
190		  0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 }
191	},
192	{
193		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
194		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
195		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
196		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
197		16,
198		{ 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
199		  0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }
200	},
201	{
202		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
203		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
204		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
205		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
206		  0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
207		  0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
208		  0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 },
209		40,
210		{ 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
211		  0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }
212	},
213	{
214		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
215		  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
216		{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
217		  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
218		  0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
219		  0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
220		  0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
221		  0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
222		  0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
223		  0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
224		64,
225		{ 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
226		  0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe }
227	},
228};
229
230
231int main(int argc, char *argv[])
232{
233	u8 kek[] = {
234		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
235		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
236	};
237	u8 plain[] = {
238		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
239		0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
240	};
241	u8 crypt[] = {
242		0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
243		0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
244		0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
245	};
246	u8 result[24];
247	int ret = 0;
248	unsigned int i;
249	struct omac1_test_vector *tv;
250
251	if (aes_wrap(kek, 2, plain, result)) {
252		printf("AES-WRAP-128-128 reported failure\n");
253		ret++;
254	}
255	if (memcmp(result, crypt, 24) != 0) {
256		printf("AES-WRAP-128-128 failed\n");
257		ret++;
258	}
259	if (aes_unwrap(kek, 2, crypt, result)) {
260		printf("AES-UNWRAP-128-128 reported failure\n");
261		ret++;
262	}
263	if (memcmp(result, plain, 16) != 0) {
264		printf("AES-UNWRAP-128-128 failed\n");
265		ret++;
266		for (i = 0; i < 16; i++)
267			printf(" %02x", result[i]);
268		printf("\n");
269	}
270
271	test_aes_perf();
272
273	for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) {
274		tv = &test_vectors[i];
275		omac1_aes_128(tv->k, tv->msg, tv->msg_len, result);
276		if (memcmp(result, tv->tag, 16) != 0) {
277			printf("OMAC1-AES-128 test vector %d failed\n", i);
278			ret++;
279		}
280
281		if (tv->msg_len > 1) {
282			const u8 *addr[2];
283			size_t len[2];
284
285			addr[0] = tv->msg;
286			len[0] = 1;
287			addr[1] = tv->msg + 1;
288			len[1] = tv->msg_len - 1;
289
290			omac1_aes_128_vector(tv->k, 2, addr, len, result);
291			if (memcmp(result, tv->tag, 16) != 0) {
292				printf("OMAC1-AES-128(vector) test vector %d "
293				       "failed\n", i);
294				ret++;
295			}
296		}
297	}
298
299	ret += test_eax();
300
301	ret += test_cbc();
302
303	if (ret)
304		printf("FAILED!\n");
305
306	return ret;
307}
308