Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Aug 2008 18:35:55 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 148022 for review
Message-ID:  <200808211835.m7LIZtJh078242@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=148022

Change 148022 by sam@sam_ebb on 2008/08/21 18:35:50

	checkpoint vap rewrite; untested because we need to figure out
	how to clone a vap within the kernel

Affected files ...

.. //depot/projects/vap/tools/regression/net80211/tkip/test_tkip.c#3 edit

Differences ...

==== //depot/projects/vap/tools/regression/net80211/tkip/test_tkip.c#3 (text+ko) ====

@@ -44,8 +44,11 @@
 
 #include <net/if.h>
 #include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_clone.h>
 
 #include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_regdomain.h>
 
 /*
 Key	12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12
@@ -178,15 +181,55 @@
 	dumpdata("Reference", ref, reflen);
 }
 
+static struct mbuf *
+formpacket(const struct ieee80211_cipher *cip, const void *plaintext, int len)
+{
+	struct mbuf *m;
+
+	m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
+	KASSERT(m != NULL, ("cannot allocate mbuf!"));
+
+	m->m_data += cip->ic_header;
+	m_append(m, len, plaintext);
+
+	return m;
+}
+
+static int
+verifypacket(const struct mbuf *m, const void *data, int len, const char *what)
+{
+	void *buf;
+	int ok;
+
+	if (m->m_pkthdr.len != len) {
+		printf("FAIL: %s botch; length mismatch\n", what);
+		cmpfail(mtod(m, const void *), m->m_pkthdr.len, data, len);
+		return 0;
+	}
+
+	buf = malloc(m->m_pkthdr.len, M_TEMP, M_NOWAIT);
+	if (buf == NULL) {
+		printf("ERROR: cannot allocate temp buffer for packet check\n");
+		return 0;
+	}
+	m_copydata(m, 0, m->m_pkthdr.len, buf);
+	ok = (memcmp(buf, data, len) == 0);
+	free(buf, M_TEMP);
+	if (!ok) {
+		printf("FAIL: %s does not compare\n", what);
+		cmpfail(buf, m->m_pkthdr.len, data, len);
+	}
+	return ok;
+}
+
 static int
-runtest(struct ieee80211com *ic, struct ciphertest *t)
+runtest(struct ieee80211vap *vap, struct ciphertest *t)
 {
 	struct tkip_ctx *ctx;
 	struct ieee80211_key key;
 	struct mbuf *m = NULL;
 	const struct ieee80211_cipher *cip;
-	u_int8_t mac[IEEE80211_ADDR_LEN];
-	u_int len;
+	int hdrlen;
 
 	printf("%s: ", t->name);
 
@@ -196,7 +239,7 @@
 	memset(&key, 0, sizeof(key));
 	key.wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
 	key.wk_cipher = &ieee80211_cipher_none;
-	if (!ieee80211_crypto_newkey(ic, IEEE80211_CIPHER_TKIP,
+	if (!ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_TKIP,
 	    IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, &key)) {
 		printf("FAIL: ieee80211_crypto_newkey failed\n");
 		goto bad;
@@ -204,9 +247,9 @@
 
 	memcpy(key.wk_key, t->key, t->key_len);
 	key.wk_keylen = 128/NBBY;
-	key.wk_keyrsc = 0;
+	key.wk_keyrsc[IEEE80211_NONQOS_TID] = 0;
 	key.wk_keytsc = t->pn;
-	if (!ieee80211_crypto_setkey(ic, &key, mac)) {
+	if (!ieee80211_crypto_setkey(vap, &key)) {
 		printf("FAIL: ieee80211_crypto_setkey failed\n");
 		goto bad;
 	}
@@ -215,35 +258,20 @@
 	 * Craft frame from plaintext data.
 	 */
 	cip = key.wk_cipher;
-	m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
-	m->m_data += cip->ic_header;
-	len = t->plaintext_len - IEEE80211_WEP_MICLEN;
-	memcpy(mtod(m, void *), t->plaintext, len);
-	m->m_len = len;
-	m->m_pkthdr.len = m->m_len;
+	m = formpacket(cip, t->plaintext,
+	    t->plaintext_len - IEEE80211_WEP_MICLEN);
+	hdrlen = ieee80211_anyhdrsize(t->plaintext);
 
 	/*
 	 * Add MIC.
 	 */
-	if (!ieee80211_crypto_enmic(ic, &key, m)) {
+	if (!ieee80211_crypto_enmic(vap, &key, m, 0)) {
 		printf("FAIL: tkip enmic failed\n");
 		goto bad;
 	}
-	/*
-	 * Verify: frame length, frame contents.
-	 */
-	if (m->m_pkthdr.len != t->plaintext_len) {
-		printf("FAIL: enmic botch; length mismatch\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->plaintext, t->plaintext_len);
+	if (!verifypacket(m, t->plaintext, t->plaintext_len, "enmic"))
 		goto bad;
-	}
-	if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
-		printf("FAIL: enmic botch\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->plaintext, t->plaintext_len);
-		goto bad;
-	}
+
 	/*
 	 * Encrypt frame w/ MIC.
 	 */
@@ -260,20 +288,14 @@
 		cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak),
 			t->phase1, t->phase1_len);
 		goto bad;
-	} else if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) {
+	}
+	if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) {
 		printf("FAIL: encrypt phase2 botch\n");
 		cmpfail(ctx->tx_rc4key, sizeof(ctx->tx_rc4key),
 			t->phase2, t->phase2_len);
 		goto bad;
-	} else if (m->m_pkthdr.len != t->encrypted_len) {
-		printf("FAIL: encrypt data length mismatch\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->encrypted, t->encrypted_len);
-		goto bad;
-	} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
-		printf("FAIL: encrypt data does not compare\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->encrypted, t->encrypted_len);
+	}
+	if (!verifypacket(m, t->encrypted, t->encrypted_len, "encrypt data")) {
 		dumpdata("Plaintext", t->plaintext, t->plaintext_len);
 		goto bad;
 	}
@@ -281,7 +303,7 @@
 	/*
 	 * Decrypt frame.
 	 */
-	if (!cip->ic_decap(&key, m)) {
+	if (!cip->ic_decap(&key, m, hdrlen)) {
 		printf("tkip decap failed\n");
 		/*
 		 * Check reason for failure: phase1, phase2, frame data (ICV).
@@ -304,22 +326,12 @@
 	/*
 	 * Verify: frame length, frame contents.
 	 */
-	if (m->m_pkthdr.len != t->plaintext_len) {
-		printf("FAIL: decap botch; length mismatch\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->plaintext, t->plaintext_len);
+	if (!verifypacket(m, t->plaintext, t->plaintext_len, "decap"))
 		goto bad;
-	}
-	if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
-		printf("FAIL: decap botch; data does not compare\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->plaintext, t->plaintext_len);
-		goto bad;
-	}
 	/*
 	 * De-MIC decrypted frame.
 	 */
-	if (!ieee80211_crypto_demic(ic, &key, m)) {
+	if (!ieee80211_crypto_demic(vap, &key, m, 0)) {
 		printf("FAIL: tkip demic failed\n");
 		goto bad;
 	}
@@ -329,7 +341,7 @@
 bad:
 	if (m != NULL)
 		m_freem(m);
-	ieee80211_crypto_delkey(ic, &key);
+	ieee80211_crypto_delkey(vap, &key);
 	return 0;
 }
 
@@ -340,28 +352,93 @@
 static	int debug = 0;
 static	int tests = -1;
 
+static struct ieee80211vap *
+fake_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
+	int opmode, int flags,
+	const uint8_t bssid[IEEE80211_ADDR_LEN],
+	const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+	struct ieee80211vap *vap;
+
+	vap = malloc(sizeof(*vap), M_80211_VAP, M_WAITOK | M_ZERO);
+	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+	ieee80211_vap_attach(vap,
+	    ieee80211_media_change, ieee80211_media_status);
+	return vap;
+}
+
+static void
+fake_vap_delete(struct ieee80211vap *vap)
+{
+	ieee80211_vap_detach(vap);
+	free(vap, M_80211_VAP);
+}
+
 static int
 init_crypto_tkip_test(void)
 {
 #define	N(a)	(sizeof(a)/sizeof(a[0]))
-	struct ieee80211com ic;
-	int i, pass, total;
+	struct ifnet *ifp, *vifp;
+	struct ieee80211com *ic;
+	struct ieee80211_clone_params icp;
+	char ifname[IFNAMSIZ];
+	struct ieee80211vap *vap;
+	int pass = 0, total = 0, i, error;
+	uint8_t bands;
+
+	ifp = if_alloc(IFT_IEEE80211);
+	if (ifp == NULL) {
+		printf("%s: unable to allocate ifnet!\n", __func__);
+		return -1;
+	}
+	if_initname(ifp, "fake", 0);
+	ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+	ic = ifp->if_l2com;
+	ic->ic_caps = IEEE80211_C_STA;
+	ic->ic_opmode = IEEE80211_M_STA;
+	ic->ic_vap_create = fake_vap_create;
+	ic->ic_vap_delete = fake_vap_delete;
+	bands = 0;
+	setbit(&bands, IEEE80211_MODE_11B);
+	ieee80211_init_channels(ic, NULL, &bands);
+	ieee80211_ifattach(ic);
+
+	memset(&icp, 0, sizeof(icp));
+	strlcpy(icp.icp_parent, ifp->if_xname, sizeof(icp.icp_parent));
+	icp.icp_opmode = IEEE80211_M_STA;
 
-	memset(&ic, 0, sizeof(ic));
+	strlcpy(ifname, "wlan", sizeof(ifname));
+	error = if_clone_create(ifname, sizeof(ifname), (caddr_t) &icp);
+	if (error != 0) {
+		printf("%s: unable to clone vap (error %d)!\n",
+		    __func__, error);
+		pass = -1;
+		goto bad;
+	}
+	vifp = ifunit(ifname);
+	if (vifp == NULL) {
+		printf("%s: unable to locate vap %s!\n", __func__, ifname);
+		pass = -1;
+		goto bad;
+	}
+	vap = vifp->if_softc;
 	if (debug)
-		ic.ic_debug = IEEE80211_MSG_CRYPTO;
-	ieee80211_crypto_attach(&ic);
+		vap->iv_debug = IEEE80211_MSG_CRYPTO;
 
 	pass = 0;
 	total = 0;
 	for (i = 0; i < N(tkiptests); i++)
 		if (tests & (1<<i)) {
 			total++;
-			pass += runtest(&ic, &tkiptests[i]);
+			pass += runtest(vap, &tkiptests[i]);
 		}
 	printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total);
-	ieee80211_crypto_detach(&ic);
-	return (pass == total ? 0 : -1);
+bad:
+	ieee80211_ifdetach(ic);
+	if_free(ifp);
+
+	return (pass == -1 ? -1 : pass == total);
 #undef N
 }
 
@@ -370,7 +447,8 @@
 {
 	switch (type) {
 	case MOD_LOAD:
-		(void) init_crypto_tkip_test();
+		if (init_crypto_tkip_test() < 0)
+			return EIO;
 		return 0;
 	case MOD_UNLOAD:
 		return 0;
@@ -386,3 +464,4 @@
 DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
 MODULE_VERSION(test_tkip, 1);
 MODULE_DEPEND(test_tkip, wlan, 1, 1, 1);
+MODULE_DEPEND(test_tkip, wlan_tkip, 1, 1, 1);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808211835.m7LIZtJh078242>