xref: /freebsd/tools/regression/net80211/tkip/test_tkip.c (revision 7afb8adff33d47f10a11368ff54bb2eec5b30165)
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,
200 	    IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, &key)) {
201 		printf("FAIL: ieee80211_crypto_newkey failed\n");
202 		goto bad;
203 	}
204 
205 	memcpy(key.wk_key, t->key, t->key_len);
206 	key.wk_keylen = 128/NBBY;
207 	key.wk_keyrsc = 0;
208 	key.wk_keytsc = t->pn;
209 	if (!ieee80211_crypto_setkey(ic, &key, mac)) {
210 		printf("FAIL: ieee80211_crypto_setkey failed\n");
211 		goto bad;
212 	}
213 
214 	/*
215 	 * Craft frame from plaintext data.
216 	 */
217 	cip = key.wk_cipher;
218 	m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
219 	m->m_data += cip->ic_header;
220 	len = t->plaintext_len - IEEE80211_WEP_MICLEN;
221 	memcpy(mtod(m, void *), t->plaintext, len);
222 	m->m_len = len;
223 	m->m_pkthdr.len = m->m_len;
224 
225 	/*
226 	 * Add MIC.
227 	 */
228 	if (!ieee80211_crypto_enmic(ic, &key, m)) {
229 		printf("FAIL: tkip enmic failed\n");
230 		goto bad;
231 	}
232 	/*
233 	 * Verify: frame length, frame contents.
234 	 */
235 	if (m->m_pkthdr.len != t->plaintext_len) {
236 		printf("FAIL: enmic botch; length mismatch\n");
237 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
238 			t->plaintext, t->plaintext_len);
239 		goto bad;
240 	}
241 	if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
242 		printf("FAIL: enmic botch\n");
243 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
244 			t->plaintext, t->plaintext_len);
245 		goto bad;
246 	}
247 	/*
248 	 * Encrypt frame w/ MIC.
249 	 */
250 	if (!cip->ic_encap(&key, m, t->keyix<<6)) {
251 		printf("FAIL: tkip encap failed\n");
252 		goto bad;
253 	}
254 	/*
255 	 * Verify: phase1, phase2, frame length, frame contents.
256 	 */
257 	ctx = key.wk_private;
258 	if (memcmp(ctx->tx_ttak, t->phase1, t->phase1_len)) {
259 		printf("FAIL: encrypt phase1 botch\n");
260 		cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak),
261 			t->phase1, t->phase1_len);
262 		goto bad;
263 	} else if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) {
264 		printf("FAIL: encrypt phase2 botch\n");
265 		cmpfail(ctx->tx_rc4key, sizeof(ctx->tx_rc4key),
266 			t->phase2, t->phase2_len);
267 		goto bad;
268 	} else if (m->m_pkthdr.len != t->encrypted_len) {
269 		printf("FAIL: encrypt data length mismatch\n");
270 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
271 			t->encrypted, t->encrypted_len);
272 		goto bad;
273 	} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
274 		printf("FAIL: encrypt data does not compare\n");
275 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
276 			t->encrypted, t->encrypted_len);
277 		dumpdata("Plaintext", t->plaintext, t->plaintext_len);
278 		goto bad;
279 	}
280 
281 	/*
282 	 * Decrypt frame.
283 	 */
284 	if (!cip->ic_decap(&key, m)) {
285 		printf("tkip decap failed\n");
286 		/*
287 		 * Check reason for failure: phase1, phase2, frame data (ICV).
288 		 */
289 		if (memcmp(ctx->rx_ttak, t->phase1, t->phase1_len)) {
290 			printf("FAIL: decrypt phase1 botch\n");
291 			cmpfail(ctx->rx_ttak, sizeof(ctx->rx_ttak),
292 				t->phase1, t->phase1_len);
293 		} else if (memcmp(ctx->rx_rc4key, t->phase2, t->phase2_len)) {
294 			printf("FAIL: decrypt phase2 botch\n");
295 			cmpfail(ctx->rx_rc4key, sizeof(ctx->rx_rc4key),
296 				t->phase2, t->phase2_len);
297 		} else {
298 			printf("FAIL: decrypt data does not compare\n");
299 			cmpfail(mtod(m, const void *), m->m_pkthdr.len,
300 				t->plaintext, t->plaintext_len);
301 		}
302 		goto bad;
303 	}
304 	/*
305 	 * Verify: frame length, frame contents.
306 	 */
307 	if (m->m_pkthdr.len != t->plaintext_len) {
308 		printf("FAIL: decap botch; length mismatch\n");
309 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
310 			t->plaintext, t->plaintext_len);
311 		goto bad;
312 	}
313 	if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
314 		printf("FAIL: decap botch; data does not compare\n");
315 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
316 			t->plaintext, t->plaintext_len);
317 		goto bad;
318 	}
319 	/*
320 	 * De-MIC decrypted frame.
321 	 */
322 	if (!ieee80211_crypto_demic(ic, &key, m)) {
323 		printf("FAIL: tkip demic failed\n");
324 		goto bad;
325 	}
326 	/* XXX check frame length and contents... */
327 	printf("PASS\n");
328 	return 1;
329 bad:
330 	if (m != NULL)
331 		m_freem(m);
332 	ieee80211_crypto_delkey(ic, &key);
333 	return 0;
334 }
335 
336 /*
337  * Module glue.
338  */
339 
340 static	int debug = 0;
341 static	int tests = -1;
342 
343 static int
344 init_crypto_tkip_test(void)
345 {
346 #define	N(a)	(sizeof(a)/sizeof(a[0]))
347 	struct ieee80211com ic;
348 	int i, pass, total;
349 
350 	memset(&ic, 0, sizeof(ic));
351 	if (debug)
352 		ic.ic_debug = IEEE80211_MSG_CRYPTO;
353 	ieee80211_crypto_attach(&ic);
354 
355 	pass = 0;
356 	total = 0;
357 	for (i = 0; i < N(tkiptests); i++)
358 		if (tests & (1<<i)) {
359 			total++;
360 			pass += runtest(&ic, &tkiptests[i]);
361 		}
362 	printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total);
363 	ieee80211_crypto_detach(&ic);
364 	return (pass == total ? 0 : -1);
365 #undef N
366 }
367 
368 static int
369 test_tkip_modevent(module_t mod, int type, void *unused)
370 {
371 	switch (type) {
372 	case MOD_LOAD:
373 		(void) init_crypto_tkip_test();
374 		return 0;
375 	case MOD_UNLOAD:
376 		return 0;
377 	}
378 	return EINVAL;
379 }
380 
381 static moduledata_t test_tkip_mod = {
382 	"test_tkip",
383 	test_tkip_modevent,
384 	0
385 };
386 DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
387 MODULE_VERSION(test_tkip, 1);
388 MODULE_DEPEND(test_tkip, wlan, 1, 1, 1);
389