Page MenuHomeFreeBSD

D46668.id.diff
No OneTemporary

D46668.id.diff

diff --git a/sys/dev/ath/if_ath_keycache.c b/sys/dev/ath/if_ath_keycache.c
--- a/sys/dev/ath/if_ath_keycache.c
+++ b/sys/dev/ath/if_ath_keycache.c
@@ -201,6 +201,16 @@
int ret;
memset(&hk, 0, sizeof(hk));
+
+ /*
+ * If it's a IGTK key then just plain ignore it;
+ * it's already marked as handled in software and we don't
+ * need a keycache entry for it.
+ */
+ if (ieee80211_is_key_igtk(vap, k)) {
+ return (1);
+ }
+
/*
* Software crypto uses a "clear key" so non-crypto
* state kept in the key cache are maintained and
@@ -431,6 +441,19 @@
* multi-station operation.
*/
if (k->wk_keyix != IEEE80211_KEYIX_NONE) {
+
+ /*
+ * Skip IGTK keys; they're global but not used
+ * in the normal hardware keyix slots.
+ */
+ if (ieee80211_is_key_igtk(vap, k)) {
+ DPRINTF(sc, ATH_DEBUG_KEYCACHE,
+ "%s: iGTK key; skipping\n", __func__);
+ *keyix = *rxkeyix =
+ ieee80211_crypto_get_key_igtk_idx(vap, k);
+ return 1;
+ }
+
/*
* Only global keys should have key index assigned.
*/
@@ -440,6 +463,9 @@
"%s: bogus group key\n", __func__);
return 0;
}
+
+ /* TODO: bogus BIP key */
+
if (vap->iv_opmode != IEEE80211_M_HOSTAP ||
!(k->wk_flags & IEEE80211_KEY_GROUP) ||
!sc->sc_mcastkey) {
@@ -501,7 +527,17 @@
if (cip->ic_cipher == IEEE80211_CIPHER_TKIP &&
(k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic)
ath_hal_keyreset(ah, keyix+32); /* RX key */
- if (keyix >= IEEE80211_WEP_NKID) {
+
+ /*
+ * Skip BIP keys; key indexes 4 and 5 are valid non-global
+ * keycache entries
+ */
+ if (ieee80211_is_key_igtk(vap, k)) {
+ DPRINTF(sc, ATH_DEBUG_KEYCACHE,
+ "%s: keyix=%d but igtk key; skipping\n",
+ __func__,
+ keyix);
+ } else if (keyix >= IEEE80211_WEP_NKID) {
/*
* Don't touch keymap entries for global keys so
* they are never considered for dynamic allocation.
diff --git a/sys/dev/rtwn/if_rtwn_cam.c b/sys/dev/rtwn/if_rtwn_cam.c
--- a/sys/dev/rtwn/if_rtwn_cam.c
+++ b/sys/dev/rtwn/if_rtwn_cam.c
@@ -185,11 +185,34 @@
uint8_t algo, keyid;
int i, error;
+
+ /*
+ * TODO: what about IGTK keys (4, 5) ? Would they allocated
+ * as "real" keycache entries?
+ */
+
+ /*
+ * TODO: I likely need to clean up by introducing
+ * "are these WEP group keys" and "are these IGTK group keys"
+ * inline functions and use them here, not the wk_keyix thing).
+ */
+
if (sc->sc_hwcrypto == RTWN_CRYPTO_FULL &&
- k->wk_keyix < IEEE80211_WEP_NKID)
+ k->wk_keyix < IEEE80211_WEP_NKID) {
+ keyid = k->wk_keyix;
+ } else if (sc->sc_hwcrypto == RTWN_CRYPTO_FULL &&
+ k->wk_flags & IEEE80211_KEY_GROUP) {
keyid = k->wk_keyix;
- else
+ } else if (sc->sc_hwcrypto == RTWN_CRYPTO_FULL &&
+ (k->wk_flags & (IEEE80211_KEY_GROUP | IEEE80211_KEY_IGTK)) &&
+ (k->wk_keyix == 4 || k->wk_keyix == 5)) {
+ device_printf(sc->sc_dev, "%s: got group key idx 4/5? (%d) (flags=0x%08x)\n",
+ __func__, k->wk_keyix, k->wk_flags);
keyid = 0;
+ } else {
+ keyid = 0;
+ }
+
/* Map net80211 cipher to HW crypto algorithm. */
switch (k->wk_cipher->ic_cipher) {
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -1472,7 +1472,9 @@
#define IEEE80211_WEP_TOTLEN (IEEE80211_WEP_IVLEN + \
IEEE80211_WEP_KIDLEN + \
IEEE80211_WEP_CRCLEN)
-#define IEEE80211_WEP_NKID 4 /* number of key ids */
+#define IEEE80211_WEP_NKID 4 /* number of WEP/global key ids */
+#define IEEE80211_MAX_NKID 6 /* number of WEP/global/iGTK key ids */
+#define IEEE80211_IGTK_NKID 2 /* number of iGTK key IDs */
/*
* 802.11i defines an extended IV for use with non-WEP ciphers.
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -2693,6 +2693,7 @@
ieee80211_is_key_global(const struct ieee80211vap *vap,
const struct ieee80211_key *key)
{
+
return (&vap->iv_nw_keys[0] <= key &&
key < &vap->iv_nw_keys[IEEE80211_WEP_NKID]);
}
@@ -2705,7 +2706,9 @@
ieee80211_is_key_igtk(const struct ieee80211vap *vap,
const struct ieee80211_key *key)
{
- return false;
+
+ /* TODO: don't hard-code these two key indexes? */
+ return (key == &vap->iv_nw_keys[4] || key == &vap->iv_nw_keys[5]);
}
/*
@@ -2715,10 +2718,7 @@
ieee80211_is_key_unicast(const struct ieee80211vap *vap,
const struct ieee80211_key *key)
{
- /*
- * This is a short-cut for now; eventually we will need
- * to support multiple unicast keys, IGTK, etc) so we
- * will absolutely need to fix the key flags.
- */
- return (!ieee80211_is_key_global(vap, key));
+
+ return (!(ieee80211_is_key_global(vap, key)
+ || ieee80211_is_key_igtk(vap, key)));
}
diff --git a/sys/net80211/ieee80211_crypto.h b/sys/net80211/ieee80211_crypto.h
--- a/sys/net80211/ieee80211_crypto.h
+++ b/sys/net80211/ieee80211_crypto.h
@@ -91,6 +91,7 @@
#define IEEE80211_KEY_NOIVMGT 0x00008000 /* don't insert IV/MIC for mgmt */
#define IEEE80211_KEY_NOMIC 0x00010000 /* don't insert MIC for !mgmt */
#define IEEE80211_KEY_NOMICMGT 0x00020000 /* don't insert MIC for mgmt */
+#define IEEE80211_KEY_IGTK 0x00040000 /* key is used for IGTK */
ieee80211_keyix wk_keyix; /* h/w key index */
ieee80211_keyix wk_rxkeyix; /* optional h/w rx key index */
@@ -106,7 +107,7 @@
};
#define IEEE80211_KEY_COMMON /* common flags passed in by apps */\
(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP | \
- IEEE80211_KEY_NOREPLAY)
+ IEEE80211_KEY_NOREPLAY | IEEE80211_KEY_IGTK)
#define IEEE80211_KEY_SWCRYPT \
(IEEE80211_KEY_SWENCRYPT | IEEE80211_KEY_SWDECRYPT)
@@ -231,6 +232,8 @@
int ieee80211_crypto_get_key_wepidx(const struct ieee80211vap *,
const struct ieee80211_key *k);
+int ieee80211_crypto_get_key_igtk_idx(const struct ieee80211vap *,
+ const struct ieee80211_key *k);
uint8_t ieee80211_crypto_get_keyid(struct ieee80211vap *vap,
struct ieee80211_key *k);
struct ieee80211_key *ieee80211_crypto_get_txkey(struct ieee80211_node *,
diff --git a/sys/net80211/ieee80211_crypto.c b/sys/net80211/ieee80211_crypto.c
--- a/sys/net80211/ieee80211_crypto.c
+++ b/sys/net80211/ieee80211_crypto.c
@@ -41,6 +41,7 @@
#include <net/if.h>
#include <net/if_media.h>
+#include <net/if_var.h> /* ic_printf */
#include <net/ethernet.h> /* XXX ETHER_HDR_LEN */
#include <net80211/ieee80211_var.h>
@@ -231,9 +232,11 @@
/* NB: we assume everything is pre-zero'd */
vap->iv_max_keyix = IEEE80211_WEP_NKID;
vap->iv_def_txkey = IEEE80211_KEYIX_NONE;
- for (i = 0; i < IEEE80211_WEP_NKID; i++)
+
+ for (i = 0; i < IEEE80211_MAX_NKID; i++)
ieee80211_crypto_resetkey(vap, &vap->iv_nw_keys[i],
IEEE80211_KEYIX_NONE);
+
/*
* Initialize the driver key support routines to noop entries.
* This is useful especially for the cipher test modules.
@@ -546,7 +549,7 @@
int i;
ieee80211_key_update_begin(vap);
- for (i = 0; i < IEEE80211_WEP_NKID; i++)
+ for (i = 0; i < IEEE80211_MAX_NKID; i++)
(void) _ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[i]);
ieee80211_key_update_end(vap);
}
@@ -613,6 +616,28 @@
}
/*
+ * Return index if the key is an IGTK key (4..5); -1 otherwise.
+ *
+ * This is different to "get_keyid" which defaults to returning
+ * 0 for unicast keys; it assumes that it won't be used for WEP.
+ */
+int
+ieee80211_crypto_get_key_igtk_idx(const struct ieee80211vap *vap,
+ const struct ieee80211_key *k)
+{
+ if (ieee80211_is_key_igtk(vap, k)) {
+ /* XXX TODO: i hate this */
+ return (k - vap->iv_nw_keys);
+ }
+
+ return (-1);
+}
+
+/*
+ * Return the group or unicast key.
+ *
+ * Don't call this for IGTK keyx!
+ *
* Note: only supports a single unicast key (0).
*/
uint8_t
@@ -622,6 +647,16 @@
return (k - vap->iv_nw_keys);
}
+ /*
+ * TODO: I wish this function could return an error,
+ * but then I'd have to audit all the places that called it
+ * and make sure THEY can handle the error!
+ */
+ if (ieee80211_is_key_igtk(vap, k)) {
+ if_printf(vap->iv_ifp, "%s: IGTK key passed in! Invalid!\n",
+ __func__);
+ }
+
return (0);
}
@@ -857,11 +892,16 @@
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
if (vap->iv_state != IEEE80211_S_RUN)
continue;
+
+ /* Global/WEP keys */
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
const struct ieee80211_key *k = &vap->iv_nw_keys[i];
if (k->wk_flags & IEEE80211_KEY_DEVKEY)
dev_key_set(vap, k);
}
+
+ /* TODO: do the two iGTK keys too if the driver supports it? */
+ /* (The drivers will need to be made aware of the other two KIDs and ignore them if needed..) */
}
/*
* Unicast keys.
diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -604,7 +604,7 @@
db_printf("\tmax_keyix %u", vap->iv_max_keyix);
db_printf(" def_txkey %d", vap->iv_def_txkey);
db_printf("\n");
- for (i = 0; i < IEEE80211_WEP_NKID; i++)
+ for (i = 0; i < IEEE80211_MAX_NKID; i++)
_db_show_key("\tnw_keys[%u]", i, &vap->iv_nw_keys[i]);
db_printf("\tauth %p(%s)", vap->iv_auth, vap->iv_auth->ia_name);
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -93,7 +93,7 @@
return ENOENT;
wk = &ni->ni_ucastkey;
} else {
- if (kid >= IEEE80211_WEP_NKID)
+ if (kid >= IEEE80211_MAX_NKID)
return EINVAL;
wk = &vap->iv_nw_keys[kid];
IEEE80211_ADDR_COPY(&ik.ik_macaddr, vap->iv_bss->ni_macaddr);
@@ -1177,8 +1177,8 @@
case IEEE80211_MFP_PROTMODE_REQUIRED:
ireq->i_val = IEEE80211_MFP_REQUIRED;
break;
- }
- break;
+ }
+ break;
case IEEE80211_IOC_VHTCONF:
ireq->i_val = vap->iv_vht_flags & IEEE80211_FVHT_MASK;
break;
@@ -1227,7 +1227,7 @@
}
wk = &ni->ni_ucastkey;
} else {
- if (kid >= IEEE80211_WEP_NKID)
+ if (kid >= IEEE80211_MAX_NKID)
return EINVAL;
wk = &vap->iv_nw_keys[kid];
/*
@@ -1327,7 +1327,7 @@
ieee80211_node_delucastkey(ni);
ieee80211_free_node(ni);
} else {
- if (kid >= IEEE80211_WEP_NKID)
+ if (kid >= IEEE80211_MAX_NKID)
return EINVAL;
/* XXX error return */
ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[kid]);
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -509,7 +509,7 @@
/* Key management */
uint16_t iv_max_keyix; /* max h/w key index */
ieee80211_keyix iv_def_txkey; /* default/group tx key index */
- struct ieee80211_key iv_nw_keys[IEEE80211_WEP_NKID];
+ struct ieee80211_key iv_nw_keys[IEEE80211_MAX_NKID];
int (*iv_key_alloc)(struct ieee80211vap *,
struct ieee80211_key *,
ieee80211_keyix *, ieee80211_keyix *);

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 16, 3:03 AM (3 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31573617
Default Alt Text
D46668.id.diff (10 KB)

Event Timeline