From owner-p4-projects@FreeBSD.ORG Thu Aug 21 18:35:57 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5900E10656DC; Thu, 21 Aug 2008 18:35:56 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id ED1541065675 for ; Thu, 21 Aug 2008 18:35:55 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id D7DE18FC1C for ; Thu, 21 Aug 2008 18:35:55 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m7LIZtlF078244 for ; Thu, 21 Aug 2008 18:35:55 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m7LIZtJh078242 for perforce@freebsd.org; Thu, 21 Aug 2008 18:35:55 GMT (envelope-from sam@freebsd.org) Date: Thu, 21 Aug 2008 18:35:55 GMT Message-Id: <200808211835.m7LIZtJh078242@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 148022 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Aug 2008 18:35:57 -0000 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 #include +#include +#include #include +#include /* 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<