Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147916887
D7887.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D7887.diff
View Options
Index: head/sys/net80211/ieee80211_hostap.c
===================================================================
--- head/sys/net80211/ieee80211_hostap.c
+++ head/sys/net80211/ieee80211_hostap.c
@@ -1153,28 +1153,36 @@
* record any key length.
*/
static int
-wpa_cipher(const uint8_t *sel, uint8_t *keylen)
+wpa_cipher(const uint8_t *sel, uint8_t *keylen, uint8_t *cipher)
{
#define WPA_SEL(x) (((x)<<24)|WPA_OUI)
uint32_t w = le32dec(sel);
switch (w) {
case WPA_SEL(WPA_CSE_NULL):
- return IEEE80211_CIPHER_NONE;
+ *cipher = IEEE80211_CIPHER_NONE;
+ break;
case WPA_SEL(WPA_CSE_WEP40):
if (keylen)
*keylen = 40 / NBBY;
- return IEEE80211_CIPHER_WEP;
+ *cipher = IEEE80211_CIPHER_WEP;
+ break;
case WPA_SEL(WPA_CSE_WEP104):
if (keylen)
*keylen = 104 / NBBY;
- return IEEE80211_CIPHER_WEP;
+ *cipher = IEEE80211_CIPHER_WEP;
+ break;
case WPA_SEL(WPA_CSE_TKIP):
- return IEEE80211_CIPHER_TKIP;
+ *cipher = IEEE80211_CIPHER_TKIP;
+ break;
case WPA_SEL(WPA_CSE_CCMP):
- return IEEE80211_CIPHER_AES_CCM;
+ *cipher = IEEE80211_CIPHER_AES_CCM;
+ break;
+ default:
+ return (EINVAL);
}
- return 32; /* NB: so 1<< is discarded */
+
+ return (0);
#undef WPA_SEL
}
@@ -1212,7 +1220,7 @@
{
uint8_t len = frm[1];
uint32_t w;
- int n;
+ int error, n;
/*
* Check the length once for fixed parts: OUI, type,
@@ -1245,7 +1253,14 @@
memset(rsn, 0, sizeof(*rsn));
/* multicast/group cipher */
- rsn->rsn_mcastcipher = wpa_cipher(frm, &rsn->rsn_mcastkeylen);
+ error = wpa_cipher(frm, &rsn->rsn_mcastkeylen, &rsn->rsn_mcastcipher);
+ if (error != 0) {
+ IEEE80211_DISCARD_IE(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
+ wh, "WPA", "unknown mcast cipher suite %08X",
+ le32dec(frm));
+ return IEEE80211_REASON_GROUP_CIPHER_INVALID;
+ }
frm += 4, len -= 4;
/* unicast ciphers */
@@ -1260,13 +1275,26 @@
}
w = 0;
for (; n > 0; n--) {
- w |= 1<<wpa_cipher(frm, &rsn->rsn_ucastkeylen);
+ uint8_t cipher;
+
+ error = wpa_cipher(frm, &rsn->rsn_ucastkeylen, &cipher);
+ if (error == 0)
+ w |= 1 << cipher;
+
frm += 4, len -= 4;
}
- if (w & (1<<IEEE80211_CIPHER_TKIP))
- rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
- else
+ if (w == 0) {
+ IEEE80211_DISCARD_IE(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
+ wh, "WPA", "no usable pairwise cipher suite found (w=%d)",
+ w);
+ return IEEE80211_REASON_PAIRWISE_CIPHER_INVALID;
+ }
+ /* XXX other? */
+ if (w & (1 << IEEE80211_CIPHER_AES_CCM))
rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
+ else
+ rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
/* key management algorithms */
n = le16dec(frm);
@@ -1300,30 +1328,39 @@
* record any key length.
*/
static int
-rsn_cipher(const uint8_t *sel, uint8_t *keylen)
+rsn_cipher(const uint8_t *sel, uint8_t *keylen, uint8_t *cipher)
{
#define RSN_SEL(x) (((x)<<24)|RSN_OUI)
uint32_t w = le32dec(sel);
switch (w) {
case RSN_SEL(RSN_CSE_NULL):
- return IEEE80211_CIPHER_NONE;
+ *cipher = IEEE80211_CIPHER_NONE;
+ break;
case RSN_SEL(RSN_CSE_WEP40):
if (keylen)
*keylen = 40 / NBBY;
- return IEEE80211_CIPHER_WEP;
+ *cipher = IEEE80211_CIPHER_WEP;
+ break;
case RSN_SEL(RSN_CSE_WEP104):
if (keylen)
*keylen = 104 / NBBY;
- return IEEE80211_CIPHER_WEP;
+ *cipher = IEEE80211_CIPHER_WEP;
+ break;
case RSN_SEL(RSN_CSE_TKIP):
- return IEEE80211_CIPHER_TKIP;
+ *cipher = IEEE80211_CIPHER_TKIP;
+ break;
case RSN_SEL(RSN_CSE_CCMP):
- return IEEE80211_CIPHER_AES_CCM;
+ *cipher = IEEE80211_CIPHER_AES_CCM;
+ break;
case RSN_SEL(RSN_CSE_WRAP):
- return IEEE80211_CIPHER_AES_OCB;
+ *cipher = IEEE80211_CIPHER_AES_OCB;
+ break;
+ default:
+ return (EINVAL);
}
- return 32; /* NB: so 1<< is discarded */
+
+ return (0);
#undef WPA_SEL
}
@@ -1360,7 +1397,7 @@
{
uint8_t len = frm[1];
uint32_t w;
- int n;
+ int error, n;
/*
* Check the length once for fixed parts:
@@ -1373,6 +1410,7 @@
wh, "WPA", "not RSN, flags 0x%x", vap->iv_flags);
return IEEE80211_REASON_IE_INVALID;
}
+ /* XXX may be shorter */
if (len < 10) {
IEEE80211_DISCARD_IE(vap,
IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
@@ -1385,14 +1423,28 @@
IEEE80211_DISCARD_IE(vap,
IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
wh, "RSN", "bad version %u", w);
- return IEEE80211_REASON_IE_INVALID;
+ return IEEE80211_REASON_UNSUPP_RSN_IE_VERSION;
}
frm += 2, len -= 2;
memset(rsn, 0, sizeof(*rsn));
/* multicast/group cipher */
- rsn->rsn_mcastcipher = rsn_cipher(frm, &rsn->rsn_mcastkeylen);
+ error = rsn_cipher(frm, &rsn->rsn_mcastkeylen, &rsn->rsn_mcastcipher);
+ if (error != 0) {
+ IEEE80211_DISCARD_IE(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
+ wh, "RSN", "unknown mcast cipher suite %08X",
+ le32dec(frm));
+ return IEEE80211_REASON_GROUP_CIPHER_INVALID;
+ }
+ if (rsn->rsn_mcastcipher == IEEE80211_CIPHER_NONE) {
+ IEEE80211_DISCARD_IE(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
+ wh, "RSN", "invalid mcast cipher suite %d",
+ rsn->rsn_mcastcipher);
+ return IEEE80211_REASON_GROUP_CIPHER_INVALID;
+ }
frm += 4, len -= 4;
/* unicast ciphers */
@@ -1406,14 +1458,33 @@
return IEEE80211_REASON_IE_INVALID;
}
w = 0;
+
for (; n > 0; n--) {
- w |= 1<<rsn_cipher(frm, &rsn->rsn_ucastkeylen);
+ uint8_t cipher;
+
+ error = rsn_cipher(frm, &rsn->rsn_ucastkeylen, &cipher);
+ if (error == 0)
+ w |= 1 << cipher;
+
frm += 4, len -= 4;
}
- if (w & (1<<IEEE80211_CIPHER_TKIP))
+ if (w & (1 << IEEE80211_CIPHER_AES_CCM))
+ rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
+ else if (w & (1 << IEEE80211_CIPHER_AES_OCB))
+ rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_OCB;
+ else if (w & (1 << IEEE80211_CIPHER_TKIP))
rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
- else
- rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
+ else if ((w & (1 << IEEE80211_CIPHER_NONE)) &&
+ (rsn->rsn_mcastcipher == IEEE80211_CIPHER_WEP ||
+ rsn->rsn_mcastcipher == IEEE80211_CIPHER_TKIP))
+ rsn->rsn_ucastcipher = IEEE80211_CIPHER_NONE;
+ else {
+ IEEE80211_DISCARD_IE(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
+ wh, "RSN", "no usable pairwise cipher suite found (w=%d)",
+ w);
+ return IEEE80211_REASON_PAIRWISE_CIPHER_INVALID;
+ }
/* key management algorithms */
n = le16dec(frm);
@@ -1510,6 +1581,7 @@
else
reason = ieee80211_parse_rsn(vap, rsn, rsnparms, wh);
if (reason != 0) {
+ /* XXX wpa->rsn fallback? */
/* XXX distinguish WPA/RSN? */
vap->iv_stats.is_rx_assoc_badwpaie++;
goto bad;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 15, 3:51 PM (10 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29722190
Default Alt Text
D7887.diff (6 KB)
Attached To
Mode
D7887: net80211: improve error checking in ieee80211_parse_{wpa,rsn}
Attached
Detach File
Event Timeline
Log In to Comment