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