1 /*-
2 * Copyright (c) 2004 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") version 2 as published by the Free
18 * Software Foundation.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * TKIP test module.
34 */
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/systm.h>
38 #include <sys/mbuf.h>
39 #include <sys/module.h>
40
41 #include <sys/socket.h>
42
43 #include <net/if.h>
44 #include <net/if_var.h>
45 #include <net/if_media.h>
46
47 #include <net80211/ieee80211_var.h>
48
49 /*
50 Key 12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12
51 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12 34
52 PN 0x000000000001
53 IV 00 20 01 20 00 00 00 00
54 Phase1 bb 58 07 1f 9e 93 b4 38 25 4b
55 Phase2 00 20 01 4c fe 67 be d2 7c 86 7b 1b f8 02 8b 1c
56 */
57
58 static const u_int8_t test1_key[] = {
59 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
60 0x34, 0x56, 0x78, 0x90, 0x12,
61
62 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX MIC */
63 /*
64 * NB: 11i test vector specifies a RX MIC key different
65 * from the TX key. But this doesn't work to enmic,
66 * encrypt, then decrypt, demic. So instead we use
67 * the same key for doing the MIC in each direction.
68 *
69 * XXX need additional vectors to test alternate MIC keys
70 */
71 #if 0
72 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, /* 11i RX MIC */
73 #else
74 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX copy */
75 #endif
76 };
77 static const u_int8_t test1_phase1[] = {
78 0xbb, 0x58, 0x07, 0x1f, 0x9e, 0x93, 0xb4, 0x38, 0x25, 0x4b
79 };
80 static const u_int8_t test1_phase2[] = {
81 0x00, 0x20, 0x01, 0x4c, 0xfe, 0x67, 0xbe, 0xd2, 0x7c, 0x86,
82 0x7b, 0x1b, 0xf8, 0x02, 0x8b, 0x1c,
83 };
84
85 /* Plaintext MPDU with MIC */
86 static const u_int8_t test1_plaintext[] = {
87 0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
88 0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,
89 0xaa,0xaa,0x03,0x00,0x00,0x00,0x08,0x00,0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,
90 0x40,0x01,0xa5,0x55,0xc0,0xa8,0x0a,0x02,0xc0,0xa8,0x0a,0x01,0x08,0x00,0x3a,0xb0,
91 0x00,0x00,0x00,0x00,0xcd,0x4c,0x05,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x0a,0x0b,
92 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
93 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,
94 0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
95 /* MIC */ 0x68,0x81,0xa3,0xf3,0xd6,0x48,0xd0,0x3c
96 };
97
98 /* Encrypted MPDU with MIC and ICV */
99 static const u_int8_t test1_encrypted[] = {
100 0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
101 0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,0x00,0x20,0x01,0x20,0x00,0x00,0x00,0x00,
102 0xc0,0x0e,0x14,0xfc,0xe7,0xcf,0xab,0xc7,0x75,0x47,0xe6,0x66,0xe5,0x7c,0x0d,0xac,
103 0x70,0x4a,0x1e,0x35,0x8a,0x88,0xc1,0x1c,0x8e,0x2e,0x28,0x2e,0x38,0x01,0x02,0x7a,
104 0x46,0x56,0x05,0x5e,0xe9,0x3e,0x9c,0x25,0x47,0x02,0xe9,0x73,0x58,0x05,0xdd,0xb5,
105 0x76,0x9b,0xa7,0x3f,0x1e,0xbb,0x56,0xe8,0x44,0xef,0x91,0x22,0x85,0xd3,0xdd,0x6e,
106 0x54,0x1e,0x82,0x38,0x73,0x55,0x8a,0xdb,0xa0,0x79,0x06,0x8a,0xbd,0x7f,0x7f,0x50,
107 0x95,0x96,0x75,0xac,0xc4,0xb4,0xde,0x9a,0xa9,0x9c,0x05,0xf2,0x89,0xa7,0xc5,0x2f,
108 0xee,0x5b,0xfc,0x14,0xf6,0xf8,0xe5,0xf8
109 };
110
111 #define TEST(n,name,cipher,keyix,pn) { \
112 name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \
113 test##n##_key, sizeof(test##n##_key), \
114 test##n##_phase1, sizeof(test##n##_phase1), \
115 test##n##_phase2, sizeof(test##n##_phase2), \
116 test##n##_plaintext, sizeof(test##n##_plaintext), \
117 test##n##_encrypted, sizeof(test##n##_encrypted) \
118 }
119
120 struct ciphertest {
121 const char *name;
122 int cipher;
123 int keyix;
124 u_int64_t pn;
125 const u_int8_t *key;
126 size_t key_len;
127 const u_int8_t *phase1;
128 size_t phase1_len;
129 const u_int8_t *phase2;
130 size_t phase2_len;
131 const u_int8_t *plaintext;
132 size_t plaintext_len;
133 const u_int8_t *encrypted;
134 size_t encrypted_len;
135 } tkiptests[] = {
136 TEST(1, "TKIP test mpdu 1", TKIP, 0, 0),
137 };
138
139 struct tkip_ctx {
140 struct ieee80211com *tc_ic; /* for diagnostics */
141
142 uint16_t tx_ttak[5];
143 uint8_t tx_rc4key[16];
144
145 uint16_t rx_ttak[5];
146 int rx_phase1_done;
147 uint8_t rx_rc4key[16];
148 uint64_t rx_rsc; /* held until MIC verified */
149 };
150
151 static void
dumpdata(const char * tag,const void * p,size_t len)152 dumpdata(const char *tag, const void *p, size_t len)
153 {
154 int i;
155
156 printf("%s: 0x%p len %u", tag, p, len);
157 for (i = 0; i < len; i++) {
158 if ((i % 16) == 0)
159 printf("\n%03d:", i);
160 printf(" %02x", ((const u_int8_t *)p)[i]);
161 }
162 printf("\n");
163 }
164
165 static void
cmpfail(const void * gen,size_t genlen,const void * ref,size_t reflen)166 cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
167 {
168 int i;
169
170 for (i = 0; i < genlen; i++)
171 if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {
172 printf("first difference at byte %u\n", i);
173 break;
174 }
175 dumpdata("Generated", gen, genlen);
176 dumpdata("Reference", ref, reflen);
177 }
178
179 static int
runtest(struct ieee80211vap * vap,struct ciphertest * t)180 runtest(struct ieee80211vap *vap, struct ciphertest *t)
181 {
182 struct tkip_ctx *ctx;
183 struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];
184 struct mbuf *m = NULL;
185 const struct ieee80211_cipher *cip;
186 u_int len;
187 int hdrlen;
188
189 printf("%s: ", t->name);
190
191 /*
192 * Setup key.
193 */
194 memset(key, 0, sizeof(*key));
195 key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
196 key->wk_cipher = &ieee80211_cipher_none;
197 if (!ieee80211_crypto_newkey(vap, t->cipher,
198 IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {
199 printf("FAIL: ieee80211_crypto_newkey failed\n");
200 goto bad;
201 }
202
203 memcpy(key->wk_key, t->key, t->key_len);
204 key->wk_keylen = 128/NBBY;
205 memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc));
206 key->wk_keytsc = t->pn;
207 if (!ieee80211_crypto_setkey(vap, key)) {
208 printf("FAIL: ieee80211_crypto_setkey failed\n");
209 goto bad;
210 }
211
212 /*
213 * Craft frame from plaintext data.
214 */
215 cip = key->wk_cipher;
216 m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
217 m->m_data += cip->ic_header;
218 len = t->plaintext_len - IEEE80211_WEP_MICLEN;
219 memcpy(mtod(m, void *), t->plaintext, len);
220 m->m_len = len;
221 m->m_pkthdr.len = m->m_len;
222 hdrlen = ieee80211_anyhdrsize(mtod(m, void *));
223
224 /*
225 * Add MIC.
226 */
227 if (!ieee80211_crypto_enmic(vap, key, m, 1)) {
228 printf("FAIL: tkip enmic failed\n");
229 goto bad;
230 }
231 /*
232 * Verify: frame length, frame contents.
233 */
234 if (m->m_pkthdr.len != t->plaintext_len) {
235 printf("FAIL: enmic botch; length mismatch\n");
236 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
237 t->plaintext, t->plaintext_len);
238 goto bad;
239 }
240 if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
241 printf("FAIL: enmic botch\n");
242 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
243 t->plaintext, t->plaintext_len);
244 goto bad;
245 }
246 /*
247 * Encrypt frame w/ MIC.
248 */
249 if (!cip->ic_encap(key, m)) {
250 printf("FAIL: tkip encap failed\n");
251 goto bad;
252 }
253 /*
254 * Verify: phase1, phase2, frame length, frame contents.
255 */
256 ctx = key->wk_private;
257 if (memcmp(ctx->tx_ttak, t->phase1, t->phase1_len)) {
258 printf("FAIL: encrypt phase1 botch\n");
259 cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak),
260 t->phase1, t->phase1_len);
261 goto bad;
262 } else if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) {
263 printf("FAIL: encrypt phase2 botch\n");
264 cmpfail(ctx->tx_rc4key, sizeof(ctx->tx_rc4key),
265 t->phase2, t->phase2_len);
266 goto bad;
267 } else if (m->m_pkthdr.len != t->encrypted_len) {
268 printf("FAIL: encrypt data length mismatch\n");
269 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
270 t->encrypted, t->encrypted_len);
271 goto bad;
272 } else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
273 printf("FAIL: encrypt data does not compare\n");
274 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
275 t->encrypted, t->encrypted_len);
276 dumpdata("Plaintext", t->plaintext, t->plaintext_len);
277 goto bad;
278 }
279
280 /*
281 * Decrypt frame.
282 */
283 if (!cip->ic_decap(key, m, hdrlen)) {
284 printf("tkip decap failed\n");
285 /*
286 * Check reason for failure: phase1, phase2, frame data (ICV).
287 */
288 if (memcmp(ctx->rx_ttak, t->phase1, t->phase1_len)) {
289 printf("FAIL: decrypt phase1 botch\n");
290 cmpfail(ctx->rx_ttak, sizeof(ctx->rx_ttak),
291 t->phase1, t->phase1_len);
292 } else if (memcmp(ctx->rx_rc4key, t->phase2, t->phase2_len)) {
293 printf("FAIL: decrypt phase2 botch\n");
294 cmpfail(ctx->rx_rc4key, sizeof(ctx->rx_rc4key),
295 t->phase2, t->phase2_len);
296 } else {
297 printf("FAIL: decrypt data does not compare\n");
298 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
299 t->plaintext, t->plaintext_len);
300 }
301 goto bad;
302 }
303 /*
304 * Verify: frame length, frame contents.
305 */
306 if (m->m_pkthdr.len != t->plaintext_len) {
307 printf("FAIL: decap botch; length mismatch\n");
308 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
309 t->plaintext, t->plaintext_len);
310 goto bad;
311 }
312 if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
313 printf("FAIL: decap botch; data does not compare\n");
314 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
315 t->plaintext, t->plaintext_len);
316 goto bad;
317 }
318 /*
319 * De-MIC decrypted frame.
320 */
321 if (!ieee80211_crypto_demic(vap, key, m, 1)) {
322 printf("FAIL: tkip demic failed\n");
323 goto bad;
324 }
325 /* XXX check frame length and contents... */
326 m_freem(m);
327 ieee80211_crypto_delkey(vap, key);
328 printf("PASS\n");
329 return 1;
330 bad:
331 if (m != NULL)
332 m_freem(m);
333 ieee80211_crypto_delkey(vap, key);
334 return 0;
335 }
336
337 /*
338 * Module glue.
339 */
340
341 static int debug = 0;
342 static int tests = -1;
343
344 static int
init_crypto_tkip_test(void)345 init_crypto_tkip_test(void)
346 {
347 struct ieee80211com ic;
348 struct ieee80211vap vap;
349 struct ifnet ifp;
350 int i, pass, total;
351
352 memset(&ic, 0, sizeof(ic));
353 memset(&vap, 0, sizeof(vap));
354 memset(&ifp, 0, sizeof(ifp));
355
356 ieee80211_crypto_attach(&ic);
357
358 /* some minimal initialization */
359 strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));
360 vap.iv_ic = ⁣
361 vap.iv_ifp = &ifp;
362 if (debug)
363 vap.iv_debug = IEEE80211_MSG_CRYPTO;
364 ieee80211_crypto_vattach(&vap);
365
366 pass = 0;
367 total = 0;
368 for (i = 0; i < nitems(tkiptests); i++)
369 if (tests & (1<<i)) {
370 total++;
371 pass += runtest(&vap, &tkiptests[i]);
372 }
373 printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total);
374
375 ieee80211_crypto_vdetach(&vap);
376 ieee80211_crypto_detach(&ic);
377
378 return (pass == total ? 0 : -1);
379 }
380
381 static int
test_tkip_modevent(module_t mod,int type,void * unused)382 test_tkip_modevent(module_t mod, int type, void *unused)
383 {
384 switch (type) {
385 case MOD_LOAD:
386 (void) init_crypto_tkip_test();
387 return 0;
388 case MOD_UNLOAD:
389 return 0;
390 }
391 return EINVAL;
392 }
393
394 static moduledata_t test_tkip_mod = {
395 "test_tkip",
396 test_tkip_modevent,
397 0
398 };
399 DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
400 MODULE_VERSION(test_tkip, 1);
401 MODULE_DEPEND(test_tkip, wlan, 1, 1, 1);
402