Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152462682
D46668.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D46668.id.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D46668: net80211: add initial support for extending the global key array to include IGTK keys
Attached
Detach File
Event Timeline
Log In to Comment