xref: /freebsd/tools/regression/net80211/wep/test_wep.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
12efe996bSSam Leffler /*-
22efe996bSSam Leffler  * Copyright (c) 2004 Sam Leffler, Errno Consulting
32efe996bSSam Leffler  * All rights reserved.
42efe996bSSam Leffler  *
52efe996bSSam Leffler  * Redistribution and use in source and binary forms, with or without
62efe996bSSam Leffler  * modification, are permitted provided that the following conditions
72efe996bSSam Leffler  * are met:
82efe996bSSam Leffler  * 1. Redistributions of source code must retain the above copyright
92efe996bSSam Leffler  *    notice, this list of conditions and the following disclaimer.
102efe996bSSam Leffler  * 2. Redistributions in binary form must reproduce the above copyright
112efe996bSSam Leffler  *    notice, this list of conditions and the following disclaimer in the
122efe996bSSam Leffler  *    documentation and/or other materials provided with the distribution.
132efe996bSSam Leffler  * 3. The name of the author may not be used to endorse or promote products
142efe996bSSam Leffler  *    derived from this software without specific prior written permission.
152efe996bSSam Leffler  *
162efe996bSSam Leffler  * Alternatively, this software may be distributed under the terms of the
172efe996bSSam Leffler  * GNU General Public License ("GPL") version 2 as published by the Free
182efe996bSSam Leffler  * Software Foundation.
192efe996bSSam Leffler  *
202efe996bSSam Leffler  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
212efe996bSSam Leffler  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
222efe996bSSam Leffler  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
232efe996bSSam Leffler  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
242efe996bSSam Leffler  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
252efe996bSSam Leffler  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
262efe996bSSam Leffler  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
272efe996bSSam Leffler  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
282efe996bSSam Leffler  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
292efe996bSSam Leffler  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
302efe996bSSam Leffler  */
312efe996bSSam Leffler 
322efe996bSSam Leffler /*
332efe996bSSam Leffler  * WEP test module.
342efe996bSSam Leffler  *
352efe996bSSam Leffler  * Test vectors come from section I.7.2 of P802.11i/D7.0, October 2003.
362efe996bSSam Leffler  *
372efe996bSSam Leffler  * To use this tester load the net80211 layer (either as a module or
382efe996bSSam Leffler  * by statically configuring it into your kernel), then insmod this
392efe996bSSam Leffler  * module.  It should automatically run all test cases and print
402efe996bSSam Leffler  * information for each.  To run one or more tests you can specify a
412efe996bSSam Leffler  * tests parameter to the module that is a bit mask of the set of tests
422efe996bSSam Leffler  * you want; e.g. insmod wep_test tests=7 will run only test mpdu's
432efe996bSSam Leffler  * 1, 2, and 3.
442efe996bSSam Leffler  */
452efe996bSSam Leffler #include <sys/param.h>
462efe996bSSam Leffler #include <sys/kernel.h>
472efe996bSSam Leffler #include <sys/systm.h>
482efe996bSSam Leffler #include <sys/mbuf.h>
492efe996bSSam Leffler #include <sys/module.h>
502efe996bSSam Leffler 
512efe996bSSam Leffler #include <sys/socket.h>
522efe996bSSam Leffler 
532efe996bSSam Leffler #include <net/if.h>
54*3c64fc9cSAndriy Voskoboinyk #include <net/if_var.h>
552efe996bSSam Leffler #include <net/if_media.h>
562efe996bSSam Leffler 
572efe996bSSam Leffler #include <net80211/ieee80211_var.h>
582efe996bSSam Leffler 
592efe996bSSam Leffler /*
602efe996bSSam Leffler MPDU data
612efe996bSSam Leffler  aa aa 03 00 00 00 08 00 45 00 00 4e 66 1a 00 00 80 11 be 64 0a 00 01 22
622efe996bSSam Leffler  0a ff ff ff 00 89 00 89 00 3a 00 00 80 a6 01 10 00 01 00 00 00 00 00 00
632efe996bSSam Leffler  20 45 43 45 4a 45 48 45 43 46 43 45 50 46 45 45 49 45 46 46 43 43 41 43
642efe996bSSam Leffler  41 43 41 43 41 43 41 41 41 00 00 20 00 01
652efe996bSSam Leffler 
662efe996bSSam Leffler RC4 encryption is performed as follows:
672efe996bSSam Leffler 17
682efe996bSSam Leffler 18  Key  fb 02 9e 30 31 32 33 34
692efe996bSSam Leffler Plaintext
702efe996bSSam Leffler  aa aa 03 00 00 00 08 00 45 00 00 4e 66 1a 00 00 80 11 be 64 0a 00 01
712efe996bSSam Leffler  22 0a ff ff ff 00 89 00 89 00 3a 00 00 80 a6 01 10 00 01 00 00 00 00
722efe996bSSam Leffler  00 00 20 45 43 45 4a 45 48 45 43 46 43 45 50 46 45 45 49 45 46 46 43
732efe996bSSam Leffler  43 41 43 41 43 41 43 41 43 41 41 41 00 00 20 00 01 1b d0 b6 04
742efe996bSSam Leffler Ciphertext
752efe996bSSam Leffler  f6 9c 58 06 bd 6c e8 46 26 bc be fb 94 74 65 0a ad 1f 79 09 b0 f6 4d
762efe996bSSam Leffler  5f 58 a5 03 a2 58 b7 ed 22 eb 0e a6 49 30 d3 a0 56 a5 57 42 fc ce 14
772efe996bSSam Leffler  1d 48 5f 8a a8 36 de a1 8d f4 2c 53 80 80 5a d0 c6 1a 5d 6f 58 f4 10
782efe996bSSam Leffler  40 b2 4b 7d 1a 69 38 56 ed 0d 43 98 e7 ae e3 bf 0e 2a 2c a8 f7
792efe996bSSam Leffler The plaintext consists of the MPDU data, followed by a 4-octet CRC-32
802efe996bSSam Leffler calculated over the MPDU data.
812efe996bSSam Leffler 19  The expanded MPDU, after WEP encapsulation, is as follows:
822efe996bSSam Leffler 20
832efe996bSSam Leffler 21  IV  fb 02 9e 80
842efe996bSSam Leffler MPDU  data
852efe996bSSam Leffler  f6 9c 58 06 bd 6c e8 46 26 bc be fb 94 74 65 0a ad 1f 79 09 b0 f6 4d 5f 58 a5
862efe996bSSam Leffler  03 a2 58 b7 ed 22 eb 0e a6 49 30 d3 a0 56 a5 57 42 fc ce 14 1d 48 5f 8a a8 36
872efe996bSSam Leffler  de a1 8d f4 2c 53 80 80 5a d0 c6 1a 5d 6f 58 f4 10 40 b2 4b 7d 1a 69 38 56 ed
882efe996bSSam Leffler  0d 43 98 e7 ae e3 bf 0e
892efe996bSSam Leffler ICV  2a 2c a8 f7
902efe996bSSam Leffler */
912efe996bSSam Leffler static const u_int8_t test1_key[] = {		/* TK (w/o IV) */
922efe996bSSam Leffler 	0x30, 0x31, 0x32, 0x33, 0x34,
932efe996bSSam Leffler };
942efe996bSSam Leffler static const u_int8_t test1_plaintext[] = {	/* Plaintext MPDU */
952efe996bSSam Leffler 	0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,	/* 802.11 Header */
962efe996bSSam Leffler 	0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
972efe996bSSam Leffler 	0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
982efe996bSSam Leffler 	0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00,	/* Plaintext data */
992efe996bSSam Leffler 	0x45, 0x00, 0x00, 0x4e, 0x66, 0x1a, 0x00, 0x00,
1002efe996bSSam Leffler 	0x80, 0x11, 0xbe, 0x64, 0x0a, 0x00, 0x01, 0x22,
1012efe996bSSam Leffler 	0x0a, 0xff, 0xff, 0xff, 0x00, 0x89, 0x00, 0x89,
1022efe996bSSam Leffler 	0x00, 0x3a, 0x00, 0x00, 0x80, 0xa6, 0x01, 0x10,
1032efe996bSSam Leffler 	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1042efe996bSSam Leffler 	0x20, 0x45, 0x43, 0x45, 0x4a, 0x45, 0x48, 0x45,
1052efe996bSSam Leffler 	0x43, 0x46, 0x43, 0x45, 0x50, 0x46, 0x45, 0x45,
1062efe996bSSam Leffler 	0x49, 0x45, 0x46, 0x46, 0x43, 0x43, 0x41, 0x43,
1072efe996bSSam Leffler 	0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x41,
1082efe996bSSam Leffler 	0x41, 0x00, 0x00, 0x20, 0x00, 0x01,
1092efe996bSSam Leffler };
1102efe996bSSam Leffler static const u_int8_t test1_encrypted[] = {	/* Encrypted MPDU */
1112efe996bSSam Leffler 	0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
1122efe996bSSam Leffler 	0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
1132efe996bSSam Leffler 	0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
1142efe996bSSam Leffler 	0xfb, 0x02, 0x9e, 0x80, 0xf6, 0x9c, 0x58, 0x06,
1152efe996bSSam Leffler 	0xbd, 0x6c, 0xe8, 0x46, 0x26, 0xbc, 0xbe, 0xfb,
1162efe996bSSam Leffler 	0x94, 0x74, 0x65, 0x0a, 0xad, 0x1f, 0x79, 0x09,
1172efe996bSSam Leffler 	0xb0, 0xf6, 0x4d, 0x5f, 0x58, 0xa5, 0x03, 0xa2,
1182efe996bSSam Leffler 	0x58, 0xb7, 0xed, 0x22, 0xeb, 0x0e, 0xa6, 0x49,
1192efe996bSSam Leffler 	0x30, 0xd3, 0xa0, 0x56, 0xa5, 0x57, 0x42, 0xfc,
1202efe996bSSam Leffler 	0xce, 0x14, 0x1d, 0x48, 0x5f, 0x8a, 0xa8, 0x36,
1212efe996bSSam Leffler 	0xde, 0xa1, 0x8d, 0xf4, 0x2c, 0x53, 0x80, 0x80,
1222efe996bSSam Leffler 	0x5a, 0xd0, 0xc6, 0x1a, 0x5d, 0x6f, 0x58, 0xf4,
1232efe996bSSam Leffler 	0x10, 0x40, 0xb2, 0x4b, 0x7d, 0x1a, 0x69, 0x38,
1242efe996bSSam Leffler 	0x56, 0xed, 0x0d, 0x43, 0x98, 0xe7, 0xae, 0xe3,
1252efe996bSSam Leffler 	0xbf, 0x0e, 0x2a, 0x2c, 0xa8, 0xf7,
1262efe996bSSam Leffler };
1272efe996bSSam Leffler 
1282efe996bSSam Leffler /* XXX fix byte order of iv */
1292efe996bSSam Leffler #define	TEST(n,name,cipher,keyix,iv0,iv1,iv2,iv3) { \
1302efe996bSSam Leffler 	name, IEEE80211_CIPHER_##cipher,keyix, { iv2,iv1,iv0,iv3 }, \
1312efe996bSSam Leffler 	test##n##_key,   sizeof(test##n##_key), \
1322efe996bSSam Leffler 	test##n##_plaintext, sizeof(test##n##_plaintext), \
1332efe996bSSam Leffler 	test##n##_encrypted, sizeof(test##n##_encrypted) \
1342efe996bSSam Leffler }
1352efe996bSSam Leffler 
1362efe996bSSam Leffler struct ciphertest {
1372efe996bSSam Leffler 	const char	*name;
1382efe996bSSam Leffler 	int		cipher;
1392efe996bSSam Leffler 	int		keyix;
1402efe996bSSam Leffler 	u_int8_t	iv[4];
1412efe996bSSam Leffler 	const u_int8_t	*key;
1422efe996bSSam Leffler 	size_t		key_len;
1432efe996bSSam Leffler 	const u_int8_t	*plaintext;
1442efe996bSSam Leffler 	size_t		plaintext_len;
1452efe996bSSam Leffler 	const u_int8_t	*encrypted;
1462efe996bSSam Leffler 	size_t		encrypted_len;
1472efe996bSSam Leffler } weptests[] = {
1482efe996bSSam Leffler 	TEST(1, "WEP test mpdu 1", WEP, 2, 0xfb, 0x02, 0x9e, 0x80),
1492efe996bSSam Leffler };
1502efe996bSSam Leffler 
1512efe996bSSam Leffler static void
dumpdata(const char * tag,const void * p,size_t len)1522efe996bSSam Leffler dumpdata(const char *tag, const void *p, size_t len)
1532efe996bSSam Leffler {
1542efe996bSSam Leffler 	int i;
1552efe996bSSam Leffler 
1562efe996bSSam Leffler 	printf("%s: 0x%p len %u", tag, p, len);
1572efe996bSSam Leffler 	for (i = 0; i < len; i++) {
1582efe996bSSam Leffler 		if ((i % 16) == 0)
1592efe996bSSam Leffler 			printf("\n%03d:", i);
1602efe996bSSam Leffler 		printf(" %02x", ((const u_int8_t *)p)[i]);
1612efe996bSSam Leffler 	}
1622efe996bSSam Leffler 	printf("\n");
1632efe996bSSam Leffler }
1642efe996bSSam Leffler 
1652efe996bSSam Leffler static void
cmpfail(const void * gen,size_t genlen,const void * ref,size_t reflen)1662efe996bSSam Leffler cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
1672efe996bSSam Leffler {
1682efe996bSSam Leffler 	int i;
1692efe996bSSam Leffler 
1702efe996bSSam Leffler 	for (i = 0; i < genlen; i++)
1712efe996bSSam Leffler 		if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {
1722efe996bSSam Leffler 			printf("first difference at byte %u\n", i);
1732efe996bSSam Leffler 			break;
1742efe996bSSam Leffler 		}
1752efe996bSSam Leffler 	dumpdata("Generated", gen, genlen);
1762efe996bSSam Leffler 	dumpdata("Reference", ref, reflen);
1772efe996bSSam Leffler }
1782efe996bSSam Leffler 
1792efe996bSSam Leffler struct wep_ctx_hw {			/* for use with h/w support */
180*3c64fc9cSAndriy Voskoboinyk 	struct ieee80211vap *wc_vap;	/* for diagnostics+statistics */
181*3c64fc9cSAndriy Voskoboinyk 	struct ieee80211com *wc_ic;
182*3c64fc9cSAndriy Voskoboinyk 	uint32_t        wc_iv;		/* initial vector for crypto */
1832efe996bSSam Leffler };
1842efe996bSSam Leffler 
1852efe996bSSam Leffler static int
runtest(struct ieee80211vap * vap,struct ciphertest * t)186*3c64fc9cSAndriy Voskoboinyk runtest(struct ieee80211vap *vap, struct ciphertest *t)
1872efe996bSSam Leffler {
188*3c64fc9cSAndriy Voskoboinyk 	struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];
1892efe996bSSam Leffler 	struct mbuf *m = NULL;
1902efe996bSSam Leffler 	const struct ieee80211_cipher *cip;
1912efe996bSSam Leffler 	struct wep_ctx_hw *ctx;
192*3c64fc9cSAndriy Voskoboinyk 	int hdrlen;
1932efe996bSSam Leffler 
1942efe996bSSam Leffler 	printf("%s: ", t->name);
1952efe996bSSam Leffler 
1962efe996bSSam Leffler 	/*
1972efe996bSSam Leffler 	 * Setup key.
1982efe996bSSam Leffler 	 */
199*3c64fc9cSAndriy Voskoboinyk 	memset(key, 0, sizeof(*key));
200*3c64fc9cSAndriy Voskoboinyk 	key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
201*3c64fc9cSAndriy Voskoboinyk 	key->wk_cipher = &ieee80211_cipher_none;
202*3c64fc9cSAndriy Voskoboinyk 	if (!ieee80211_crypto_newkey(vap, t->cipher,
203*3c64fc9cSAndriy Voskoboinyk 	    IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {
2042efe996bSSam Leffler 		printf("FAIL: ieee80211_crypto_newkey failed\n");
2052efe996bSSam Leffler 		goto bad;
2062efe996bSSam Leffler 	}
2072efe996bSSam Leffler 
208*3c64fc9cSAndriy Voskoboinyk 	memcpy(key->wk_key, t->key, t->key_len);
209*3c64fc9cSAndriy Voskoboinyk 	key->wk_keylen = t->key_len;
210*3c64fc9cSAndriy Voskoboinyk 	if (!ieee80211_crypto_setkey(vap, key)) {
2112efe996bSSam Leffler 		printf("FAIL: ieee80211_crypto_setkey failed\n");
2122efe996bSSam Leffler 		goto bad;
2132efe996bSSam Leffler 	}
2142efe996bSSam Leffler 
2152efe996bSSam Leffler 	/*
2162efe996bSSam Leffler 	 * Craft frame from plaintext data.
2172efe996bSSam Leffler 	 */
218*3c64fc9cSAndriy Voskoboinyk 	cip = key->wk_cipher;
2192efe996bSSam Leffler 	m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
2202efe996bSSam Leffler 	memcpy(mtod(m, void *), t->encrypted, t->encrypted_len);
2212efe996bSSam Leffler 	m->m_len = t->encrypted_len;
2222efe996bSSam Leffler 	m->m_pkthdr.len = m->m_len;
223*3c64fc9cSAndriy Voskoboinyk 	hdrlen = ieee80211_anyhdrsize(mtod(m, void *));
2242efe996bSSam Leffler 
2252efe996bSSam Leffler 	/*
2262efe996bSSam Leffler 	 * Decrypt frame.
2272efe996bSSam Leffler 	 */
228*3c64fc9cSAndriy Voskoboinyk 	if (!cip->ic_decap(key, m, hdrlen)) {
2292efe996bSSam Leffler 		printf("FAIL: wep decap failed\n");
2302efe996bSSam Leffler 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
2312efe996bSSam Leffler 			t->plaintext, t->plaintext_len);
2322efe996bSSam Leffler 		goto bad;
2332efe996bSSam Leffler 	}
2342efe996bSSam Leffler 	/*
2352efe996bSSam Leffler 	 * Verify: frame length, frame contents.
2362efe996bSSam Leffler 	 */
2372efe996bSSam Leffler 	if (m->m_pkthdr.len != t->plaintext_len) {
2382efe996bSSam Leffler 		printf("FAIL: decap botch; length mismatch\n");
2392efe996bSSam Leffler 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
2402efe996bSSam Leffler 			t->plaintext, t->plaintext_len);
2412efe996bSSam Leffler 		goto bad;
2422efe996bSSam Leffler 	} else if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
2432efe996bSSam Leffler 		printf("FAIL: decap botch; data does not compare\n");
2442efe996bSSam Leffler 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
2456f1ca3e4SXin LI 			t->plaintext, t->plaintext_len);
2462efe996bSSam Leffler 		goto bad;
2472efe996bSSam Leffler 	}
2482efe996bSSam Leffler 
2492efe996bSSam Leffler 	/*
2502efe996bSSam Leffler 	 * Encrypt frame.
2512efe996bSSam Leffler 	 */
252*3c64fc9cSAndriy Voskoboinyk 	ctx = (struct wep_ctx_hw *) key->wk_private;
253*3c64fc9cSAndriy Voskoboinyk 	ctx->wc_vap = vap;
254*3c64fc9cSAndriy Voskoboinyk 	ctx->wc_ic = vap->iv_ic;
2552efe996bSSam Leffler 	memcpy(&ctx->wc_iv, t->iv, sizeof(t->iv));	/* for encap/encrypt */
256*3c64fc9cSAndriy Voskoboinyk 	if (!cip->ic_encap(key, m)) {
2572efe996bSSam Leffler 		printf("FAIL: wep encap failed\n");
2582efe996bSSam Leffler 		goto bad;
2592efe996bSSam Leffler 	}
2602efe996bSSam Leffler 	/*
2612efe996bSSam Leffler 	 * Verify: frame length, frame contents.
2622efe996bSSam Leffler 	 */
2632efe996bSSam Leffler 	if (m->m_pkthdr.len != t->encrypted_len) {
2642efe996bSSam Leffler 		printf("FAIL: encap data length mismatch\n");
2652efe996bSSam Leffler 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
2662efe996bSSam Leffler 			t->encrypted, t->encrypted_len);
2672efe996bSSam Leffler 		goto bad;
2682efe996bSSam Leffler 	} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
2692efe996bSSam Leffler 		printf("FAIL: encrypt data does not compare\n");
2702efe996bSSam Leffler 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
2712efe996bSSam Leffler 			t->encrypted, t->encrypted_len);
2722efe996bSSam Leffler 		dumpdata("Plaintext", t->plaintext, t->plaintext_len);
2732efe996bSSam Leffler 		goto bad;
2742efe996bSSam Leffler 	}
2752efe996bSSam Leffler 	m_freem(m);
276*3c64fc9cSAndriy Voskoboinyk 	ieee80211_crypto_delkey(vap, key);
2772efe996bSSam Leffler 	printf("PASS\n");
2782efe996bSSam Leffler 	return 1;
2792efe996bSSam Leffler bad:
2802efe996bSSam Leffler 	if (m != NULL)
2812efe996bSSam Leffler 		m_freem(m);
282*3c64fc9cSAndriy Voskoboinyk 	ieee80211_crypto_delkey(vap, key);
2832efe996bSSam Leffler 	return 0;
2842efe996bSSam Leffler }
2852efe996bSSam Leffler 
2862efe996bSSam Leffler /*
2872efe996bSSam Leffler  * Module glue.
2882efe996bSSam Leffler  */
2892efe996bSSam Leffler 
2902efe996bSSam Leffler static	int tests = -1;
2912efe996bSSam Leffler static	int debug = 0;
2922efe996bSSam Leffler 
2932efe996bSSam Leffler static int
init_crypto_wep_test(void)2942efe996bSSam Leffler init_crypto_wep_test(void)
2952efe996bSSam Leffler {
2962efe996bSSam Leffler 	struct ieee80211com ic;
297*3c64fc9cSAndriy Voskoboinyk 	struct ieee80211vap vap;
298*3c64fc9cSAndriy Voskoboinyk 	struct ifnet ifp;
2992efe996bSSam Leffler 	int i, pass, total;
3002efe996bSSam Leffler 
3012efe996bSSam Leffler 	memset(&ic, 0, sizeof(ic));
302*3c64fc9cSAndriy Voskoboinyk 	memset(&vap, 0, sizeof(vap));
303*3c64fc9cSAndriy Voskoboinyk 	memset(&ifp, 0, sizeof(ifp));
304*3c64fc9cSAndriy Voskoboinyk 
3052efe996bSSam Leffler 	ieee80211_crypto_attach(&ic);
306*3c64fc9cSAndriy Voskoboinyk 
307*3c64fc9cSAndriy Voskoboinyk 	/* some minimal initialization */
308*3c64fc9cSAndriy Voskoboinyk 	strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));
309*3c64fc9cSAndriy Voskoboinyk 	vap.iv_ic = &ic;
310*3c64fc9cSAndriy Voskoboinyk 	vap.iv_ifp = &ifp;
311*3c64fc9cSAndriy Voskoboinyk 	if (debug)
312*3c64fc9cSAndriy Voskoboinyk 		vap.iv_debug = IEEE80211_MSG_CRYPTO;
313*3c64fc9cSAndriy Voskoboinyk 	ieee80211_crypto_vattach(&vap);
314*3c64fc9cSAndriy Voskoboinyk 
3152efe996bSSam Leffler 	pass = 0;
3162efe996bSSam Leffler 	total = 0;
317*3c64fc9cSAndriy Voskoboinyk 	for (i = 0; i < nitems(weptests); i++)
3182efe996bSSam Leffler 		if (tests & (1<<i)) {
3192efe996bSSam Leffler 			total++;
320*3c64fc9cSAndriy Voskoboinyk 			pass += runtest(&vap, &weptests[i]);
3212efe996bSSam Leffler 		}
3222efe996bSSam Leffler 	printf("%u of %u 802.11i WEP test vectors passed\n", pass, total);
323*3c64fc9cSAndriy Voskoboinyk 
324*3c64fc9cSAndriy Voskoboinyk 	ieee80211_crypto_vdetach(&vap);
3252efe996bSSam Leffler 	ieee80211_crypto_detach(&ic);
326*3c64fc9cSAndriy Voskoboinyk 
3272efe996bSSam Leffler 	return (pass == total ? 0 : -1);
3282efe996bSSam Leffler }
3292efe996bSSam Leffler 
3302efe996bSSam Leffler static int
test_wep_modevent(module_t mod,int type,void * unused)3312efe996bSSam Leffler test_wep_modevent(module_t mod, int type, void *unused)
3322efe996bSSam Leffler {
3332efe996bSSam Leffler 	switch (type) {
3342efe996bSSam Leffler 	case MOD_LOAD:
3352efe996bSSam Leffler 		(void) init_crypto_wep_test();
3362efe996bSSam Leffler 		return 0;
3372efe996bSSam Leffler 	case MOD_UNLOAD:
3382efe996bSSam Leffler 		return 0;
3392efe996bSSam Leffler 	}
3402efe996bSSam Leffler 	return EINVAL;
3412efe996bSSam Leffler }
3422efe996bSSam Leffler 
3432efe996bSSam Leffler static moduledata_t test_wep_mod = {
3442efe996bSSam Leffler 	"test_wep",
3452efe996bSSam Leffler 	test_wep_modevent,
3469823d527SKevin Lo 	0
3472efe996bSSam Leffler };
3482efe996bSSam Leffler DECLARE_MODULE(test_wep, test_wep_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
3492efe996bSSam Leffler MODULE_VERSION(test_wep, 1);
3502efe996bSSam Leffler MODULE_DEPEND(test_wep, wlan, 1, 1, 1);
351