]>
Commit | Line | Data |
---|---|---|
6fc6879b JM |
1 | /* |
2 | * Test program for AES | |
3 | * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> | |
4 | * | |
0f3d578e JM |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. | |
6fc6879b JM |
7 | */ |
8 | ||
9 | #include "includes.h" | |
10 | ||
11 | #include "common.h" | |
03da66bd JM |
12 | #include "crypto/crypto.h" |
13 | #include "crypto/aes_wrap.h" | |
6fc6879b JM |
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); | |
1767f7c1 JM |
145 | if (aes_128_cbc_encrypt(tv->key, tv->iv, buf, tv->len) || |
146 | memcmp(buf, tv->cipher, tv->len) != 0) { | |
6fc6879b JM |
147 | printf("AES-CBC encrypt %d failed\n", i); |
148 | ret++; | |
149 | } | |
150 | memcpy(buf, tv->cipher, tv->len); | |
1767f7c1 JM |
151 | if (aes_128_cbc_decrypt(tv->key, tv->iv, buf, tv->len) || |
152 | memcmp(buf, tv->plain, tv->len) != 0) { | |
6fc6879b JM |
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]; | |
1767f7c1 JM |
269 | if (omac1_aes_128(tv->k, tv->msg, tv->msg_len, result) || |
270 | memcmp(result, tv->tag, 16) != 0) { | |
6fc6879b JM |
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 | ||
1767f7c1 JM |
284 | if (omac1_aes_128_vector(tv->k, 2, addr, len, |
285 | result) || | |
286 | memcmp(result, tv->tag, 16) != 0) { | |
6fc6879b JM |
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 | } |