xref: /freebsd/tools/regression/net80211/tkip/test_tkip.c (revision 6af83ee0d2941d18880b6aaa2b4facd1d30c6106)
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  * $FreeBSD$
32  */
33 
34 /*
35  * TKIP test module.
36  */
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
40 #include <sys/mbuf.h>
41 #include <sys/module.h>
42 
43 #include <sys/socket.h>
44 
45 #include <net/if.h>
46 #include <net/if_media.h>
47 
48 #include <net80211/ieee80211_var.h>
49 
50 /*
51 Key	12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12
52 	34 56 78 90 12 34 56 78 90 12 34 56 78 90 12 34
53 PN	0x000000000001
54 IV	00 20 01 20 00 00 00 00
55 Phase1	bb 58 07 1f 9e 93 b4 38 25 4b
56 Phase2	00 20 01 4c fe 67 be d2 7c 86 7b 1b f8 02 8b 1c
57 */
58 
59 static const u_int8_t test1_key[] = {
60 	0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
61 	0x34, 0x56, 0x78, 0x90, 0x12,
62 
63 	0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,		/* TX MIC */
64 	/*
65 	 * NB: 11i test vector specifies a RX MIC key different
66 	 *     from the TX key.  But this doesn't work to enmic,
67 	 *     encrypt, then decrypt, demic.  So instead we use
68 	 *     the same key for doing the MIC in each direction.
69 	 *
70 	 * XXX need additional vectors to test alternate MIC keys
71 	 */
72 #if 0
73 	0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34,		/* 11i RX MIC */
74 #else
75 	0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,		/* TX copy */
76 #endif
77 };
78 static const u_int8_t test1_phase1[] = {
79 	0xbb, 0x58, 0x07, 0x1f, 0x9e, 0x93, 0xb4, 0x38, 0x25, 0x4b
80 };
81 static const u_int8_t test1_phase2[] = {
82 	0x00, 0x20, 0x01, 0x4c, 0xfe, 0x67, 0xbe, 0xd2, 0x7c, 0x86,
83 	0x7b, 0x1b, 0xf8, 0x02, 0x8b, 0x1c,
84 };
85 
86 /* Plaintext MPDU with MIC */
87 static const u_int8_t test1_plaintext[] = {
88 0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
89 0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,
90 0xaa,0xaa,0x03,0x00,0x00,0x00,0x08,0x00,0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,
91 0x40,0x01,0xa5,0x55,0xc0,0xa8,0x0a,0x02,0xc0,0xa8,0x0a,0x01,0x08,0x00,0x3a,0xb0,
92 0x00,0x00,0x00,0x00,0xcd,0x4c,0x05,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x0a,0x0b,
93 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
94 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,
95 0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
96 /* MIC */ 0x68,0x81,0xa3,0xf3,0xd6,0x48,0xd0,0x3c
97 };
98 
99 /* Encrypted MPDU with MIC and ICV */
100 static const u_int8_t test1_encrypted[] = {
101 0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
102 0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,0x00,0x20,0x01,0x20,0x00,0x00,0x00,0x00,
103 0xc0,0x0e,0x14,0xfc,0xe7,0xcf,0xab,0xc7,0x75,0x47,0xe6,0x66,0xe5,0x7c,0x0d,0xac,
104 0x70,0x4a,0x1e,0x35,0x8a,0x88,0xc1,0x1c,0x8e,0x2e,0x28,0x2e,0x38,0x01,0x02,0x7a,
105 0x46,0x56,0x05,0x5e,0xe9,0x3e,0x9c,0x25,0x47,0x02,0xe9,0x73,0x58,0x05,0xdd,0xb5,
106 0x76,0x9b,0xa7,0x3f,0x1e,0xbb,0x56,0xe8,0x44,0xef,0x91,0x22,0x85,0xd3,0xdd,0x6e,
107 0x54,0x1e,0x82,0x38,0x73,0x55,0x8a,0xdb,0xa0,0x79,0x06,0x8a,0xbd,0x7f,0x7f,0x50,
108 0x95,0x96,0x75,0xac,0xc4,0xb4,0xde,0x9a,0xa9,0x9c,0x05,0xf2,0x89,0xa7,0xc5,0x2f,
109 0xee,0x5b,0xfc,0x14,0xf6,0xf8,0xe5,0xf8
110 };
111 
112 #define	TEST(n,name,cipher,keyix,pn) { \
113 	name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \
114 	test##n##_key,   sizeof(test##n##_key), \
115 	test##n##_phase1,   sizeof(test##n##_phase1), \
116 	test##n##_phase2,   sizeof(test##n##_phase2), \
117 	test##n##_plaintext, sizeof(test##n##_plaintext), \
118 	test##n##_encrypted, sizeof(test##n##_encrypted) \
119 }
120 
121 struct ciphertest {
122 	const char	*name;
123 	int		cipher;
124 	int		keyix;
125 	u_int64_t	pn;
126 	const u_int8_t	*key;
127 	size_t		key_len;
128 	const u_int8_t	*phase1;
129 	size_t		phase1_len;
130 	const u_int8_t	*phase2;
131 	size_t		phase2_len;
132 	const u_int8_t	*plaintext;
133 	size_t		plaintext_len;
134 	const u_int8_t	*encrypted;
135 	size_t		encrypted_len;
136 } tkiptests[] = {
137 	TEST(1, "TKIP test mpdu 1", TKIP, 0, 0),
138 };
139 
140 struct tkip_ctx {
141 	struct ieee80211com *tc_ic;	/* for diagnostics */
142 
143 	uint16_t tx_ttak[5];
144 	int	tx_phase1_done;
145 	uint8_t	tx_rc4key[16];
146 
147 	uint16_t rx_ttak[5];
148 	int	rx_phase1_done;
149 	uint8_t	rx_rc4key[16];
150 	uint64_t rx_rsc;		/* held until MIC verified */
151 };
152 
153 static void
154 dumpdata(const char *tag, const void *p, size_t len)
155 {
156 	int i;
157 
158 	printf("%s: 0x%p len %u", tag, p, len);
159 	for (i = 0; i < len; i++) {
160 		if ((i % 16) == 0)
161 			printf("\n%03d:", i);
162 		printf(" %02x", ((const u_int8_t *)p)[i]);
163 	}
164 	printf("\n");
165 }
166 
167 static void
168 cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
169 {
170 	int i;
171 
172 	for (i = 0; i < genlen; i++)
173 		if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {
174 			printf("first difference at byte %u\n", i);
175 			break;
176 		}
177 	dumpdata("Generated", gen, genlen);
178 	dumpdata("Reference", ref, reflen);
179 }
180 
181 static int
182 runtest(struct ieee80211com *ic, struct ciphertest *t)
183 {
184 	struct tkip_ctx *ctx;
185 	struct ieee80211_key key;
186 	struct mbuf *m = NULL;
187 	const struct ieee80211_cipher *cip;
188 	u_int8_t mac[IEEE80211_ADDR_LEN];
189 	u_int len;
190 
191 	printf("%s: ", t->name);
192 
193 	/*
194 	 * Setup key.
195 	 */
196 	memset(&key, 0, sizeof(key));
197 	key.wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
198 	key.wk_cipher = &ieee80211_cipher_none;
199 	if (!ieee80211_crypto_newkey(ic, IEEE80211_CIPHER_TKIP, &key)) {
200 		printf("FAIL: ieee80211_crypto_newkey failed\n");
201 		goto bad;
202 	}
203 
204 	memcpy(key.wk_key, t->key, t->key_len);
205 	key.wk_keylen = 128/NBBY;
206 	key.wk_keyrsc = 0;
207 	key.wk_keytsc = t->pn;
208 	if (!ieee80211_crypto_setkey(ic, &key, mac)) {
209 		printf("FAIL: ieee80211_crypto_setkey failed\n");
210 		goto bad;
211 	}
212 
213 	/*
214 	 * Craft frame from plaintext data.
215 	 */
216 	cip = key.wk_cipher;
217 	m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
218 	m->m_data += cip->ic_header;
219 	len = t->plaintext_len - IEEE80211_WEP_MICLEN;
220 	memcpy(mtod(m, void *), t->plaintext, len);
221 	m->m_len = len;
222 	m->m_pkthdr.len = m->m_len;
223 
224 	/*
225 	 * Add MIC.
226 	 */
227 	if (!ieee80211_crypto_enmic(ic, &key, m)) {
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, t->keyix<<6)) {
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)) {
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(ic, &key, m)) {
322 		printf("FAIL: tkip demic failed\n");
323 		goto bad;
324 	}
325 	/* XXX check frame length and contents... */
326 	printf("PASS\n");
327 	return 1;
328 bad:
329 	if (m != NULL)
330 		m_freem(m);
331 	ieee80211_crypto_delkey(ic, &key);
332 	return 0;
333 }
334 
335 /*
336  * Module glue.
337  */
338 
339 static	int debug = 0;
340 static	int tests = -1;
341 
342 static int
343 init_crypto_tkip_test(void)
344 {
345 #define	N(a)	(sizeof(a)/sizeof(a[0]))
346 	struct ieee80211com ic;
347 	int i, pass, total;
348 
349 	memset(&ic, 0, sizeof(ic));
350 	if (debug)
351 		ic.ic_debug = IEEE80211_MSG_CRYPTO;
352 	ieee80211_crypto_attach(&ic);
353 
354 	pass = 0;
355 	total = 0;
356 	for (i = 0; i < N(tkiptests); i++)
357 		if (tests & (1<<i)) {
358 			total++;
359 			pass += runtest(&ic, &tkiptests[i]);
360 		}
361 	printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total);
362 	ieee80211_crypto_detach(&ic);
363 	return (pass == total ? 0 : -1);
364 #undef N
365 }
366 
367 static int
368 test_tkip_modevent(module_t mod, int type, void *unused)
369 {
370 	switch (type) {
371 	case MOD_LOAD:
372 		(void) init_crypto_tkip_test();
373 		return 0;
374 	case MOD_UNLOAD:
375 		return 0;
376 	}
377 	return EINVAL;
378 }
379 
380 static moduledata_t test_tkip_mod = {
381 	"test_tkip",
382 	test_tkip_modevent,
383 	0
384 };
385 DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
386 MODULE_VERSION(test_tkip, 1);
387 MODULE_DEPEND(test_tkip, wlan, 1, 1, 1);
388