aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/libertas/wext.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-05-25 23:01:24 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-06-11 14:28:44 -0400
commit90a42210f275e1f828eb6c08bf8252c2d6a774e0 (patch)
tree7530def8af573622c4d2a3223eb8774ee76a0405 /drivers/net/wireless/libertas/wext.c
parent45f43de829981e9b9de56d6098d00d511b4fb56c (diff)
[PATCH] libertas: Make WPA work through supplicant handshake
Fix WPA so it works up through the supplicant 4-Way handshake process. Doesn't successfully pass traffic yet; may be problems installing the GTK to the firmware. - RSN needs to be enabled before the association command is sent - Use keys from the association request not the adapter structure - cmd_act_mac_strict_protection_enable != IW_AUTH_DROP_UNENCRYPTED - Fix network filtering logic in is_network_compatible() WPA helpers Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/wext.c')
-rw-r--r--drivers/net/wireless/libertas/wext.c92
1 files changed, 64 insertions, 28 deletions
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 40dd08018b4..2edc10c3327 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1498,6 +1498,8 @@ static void disable_wep(struct assoc_request *assoc_req)
{
int i;
+ lbs_deb_enter(LBS_DEB_WEXT);
+
/* Set Open System auth mode */
assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
@@ -1508,6 +1510,27 @@ static void disable_wep(struct assoc_request *assoc_req)
set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
+
+ lbs_deb_leave(LBS_DEB_WEXT);
+}
+
+static void disable_wpa(struct assoc_request *assoc_req)
+{
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct WLAN_802_11_KEY));
+ assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST;
+ set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
+
+ memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct WLAN_802_11_KEY));
+ assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST;
+ set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
+
+ assoc_req->secinfo.WPAenabled = 0;
+ assoc_req->secinfo.WPA2enabled = 0;
+ set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
+
+ lbs_deb_leave(LBS_DEB_WEXT);
}
/**
@@ -1540,6 +1563,7 @@ static int wlan_set_encode(struct net_device *dev,
if (dwrq->flags & IW_ENCODE_DISABLED) {
disable_wep (assoc_req);
+ disable_wpa (assoc_req);
goto out;
}
@@ -1641,6 +1665,7 @@ static int wlan_get_encodeext(struct net_device *dev,
if ( adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled) {
+ /* WEP */
ext->alg = IW_ENCODE_ALG_WEP;
ext->key_len = adapter->wep_keys[index].len;
key = &adapter->wep_keys[index].key[0];
@@ -1648,8 +1673,27 @@ static int wlan_get_encodeext(struct net_device *dev,
&& (adapter->secinfo.WPAenabled ||
adapter->secinfo.WPA2enabled)) {
/* WPA */
- ext->alg = IW_ENCODE_ALG_TKIP;
- ext->key_len = 0;
+ struct WLAN_802_11_KEY * pkey = NULL;
+
+ if ( adapter->wpa_mcast_key.len
+ && (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
+ pkey = &adapter->wpa_mcast_key;
+ else if ( adapter->wpa_unicast_key.len
+ && (adapter->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
+ pkey = &adapter->wpa_unicast_key;
+
+ if (pkey) {
+ if (pkey->type == KEY_TYPE_ID_AES) {
+ ext->alg = IW_ENCODE_ALG_CCMP;
+ } else {
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ }
+ ext->key_len = pkey->len;
+ key = &pkey->key[0];
+ } else {
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ ext->key_len = 0;
+ }
} else {
goto out;
}
@@ -1704,6 +1748,7 @@ static int wlan_set_encodeext(struct net_device *dev,
if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) {
disable_wep (assoc_req);
+ disable_wpa (assoc_req);
} else if (alg == IW_ENCODE_ALG_WEP) {
u16 is_default = 0, index, set_tx_key = 0;
@@ -1739,7 +1784,6 @@ static int wlan_set_encodeext(struct net_device *dev,
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
if (set_tx_key)
set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
-
} else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
struct WLAN_802_11_KEY * pkey;
@@ -1756,28 +1800,35 @@ static int wlan_set_encodeext(struct net_device *dev,
goto out;
}
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
pkey = &assoc_req->wpa_mcast_key;
- else
+ set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
+ } else {
pkey = &assoc_req->wpa_unicast_key;
+ set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
+ }
memset(pkey, 0, sizeof (struct WLAN_802_11_KEY));
memcpy(pkey->key, ext->key, ext->key_len);
pkey->len = ext->key_len;
- pkey->flags = KEY_INFO_WPA_ENABLED;
+ if (pkey->len)
+ pkey->flags |= KEY_INFO_WPA_ENABLED;
+ /* Do this after zeroing key structure */
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
pkey->flags |= KEY_INFO_WPA_MCAST;
- set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
} else {
pkey->flags |= KEY_INFO_WPA_UNICAST;
- set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
}
- if (alg == IW_ENCODE_ALG_TKIP)
+ if (alg == IW_ENCODE_ALG_TKIP) {
pkey->type = KEY_TYPE_ID_TKIP;
- else if (alg == IW_ENCODE_ALG_CCMP)
+ } else if (alg == IW_ENCODE_ALG_CCMP) {
pkey->type = KEY_TYPE_ID_AES;
+ } else {
+ ret = -EINVAL;
+ goto out;
+ }
/* If WPA isn't enabled yet, do that now */
if ( assoc_req->secinfo.WPAenabled == 0
@@ -1904,6 +1955,7 @@ static int wlan_set_auth(struct net_device *dev,
case IW_AUTH_CIPHER_PAIRWISE:
case IW_AUTH_CIPHER_GROUP:
case IW_AUTH_KEY_MGMT:
+ case IW_AUTH_DROP_UNENCRYPTED:
/*
* libertas does not use these parameters
*/
@@ -1913,6 +1965,7 @@ static int wlan_set_auth(struct net_device *dev,
if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) {
assoc_req->secinfo.WPAenabled = 0;
assoc_req->secinfo.WPA2enabled = 0;
+ disable_wpa (assoc_req);
}
if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
assoc_req->secinfo.WPAenabled = 1;
@@ -1927,17 +1980,6 @@ static int wlan_set_auth(struct net_device *dev,
updated = 1;
break;
- case IW_AUTH_DROP_UNENCRYPTED:
- if (dwrq->value) {
- adapter->currentpacketfilter |=
- cmd_act_mac_strict_protection_enable;
- } else {
- adapter->currentpacketfilter &=
- ~cmd_act_mac_strict_protection_enable;
- }
- updated = 1;
- break;
-
case IW_AUTH_80211_AUTH_ALG:
if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
@@ -1963,6 +2005,7 @@ static int wlan_set_auth(struct net_device *dev,
} else {
assoc_req->secinfo.WPAenabled = 0;
assoc_req->secinfo.WPA2enabled = 0;
+ disable_wpa (assoc_req);
}
updated = 1;
break;
@@ -2008,13 +2051,6 @@ static int wlan_get_auth(struct net_device *dev,
dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED;
break;
- case IW_AUTH_DROP_UNENCRYPTED:
- dwrq->value = 0;
- if (adapter->currentpacketfilter &
- cmd_act_mac_strict_protection_enable)
- dwrq->value = 1;
- break;
-
case IW_AUTH_80211_AUTH_ALG:
dwrq->value = adapter->secinfo.auth_mode;
break;