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
test_aes_perf(void)23 static 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
test_eax(void)60 static 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
test_cbc(void)104 static 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
173 struct omac1_test_vector {
174 u8 k[16];
175 u8 msg[64];
176 int msg_len;
177 u8 tag[16];
178 };
179
180 static 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
main(int argc,char * argv[])229 int 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