diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2009-07-30 12:42:08 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-04 16:44:17 -0400 |
commit | b7cfc5b35eed2fe8a5c45793e6e52ef0edddc824 (patch) | |
tree | 6831aa9f4e352eb4afa35c336ff4b243a9a1fd44 /drivers/net/wireless/rndis_wlan.c | |
parent | 9d40934e5e28314731d4b32acd2fdf5fb805a3ed (diff) |
rndis_wlan: rework key handling
Organize key data in private structure better and store WPA keys, so
they can be restored as WEP keys.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rndis_wlan.c')
-rw-r--r-- | drivers/net/wireless/rndis_wlan.c | 188 |
1 files changed, 142 insertions, 46 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 3d92b77d9599..828dc1825bba 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -413,6 +413,15 @@ static const struct ieee80211_rate rndis_rates[] = { | |||
413 | { .bitrate = 540 } | 413 | { .bitrate = 540 } |
414 | }; | 414 | }; |
415 | 415 | ||
416 | struct rndis_wlan_encr_key { | ||
417 | int len; | ||
418 | int cipher; | ||
419 | u8 material[32]; | ||
420 | u8 bssid[ETH_ALEN]; | ||
421 | bool pairwise; | ||
422 | bool tx_key; | ||
423 | }; | ||
424 | |||
416 | /* RNDIS device private data */ | 425 | /* RNDIS device private data */ |
417 | struct rndis_wlan_private { | 426 | struct rndis_wlan_private { |
418 | struct usbnet *usbdev; | 427 | struct usbnet *usbdev; |
@@ -456,9 +465,7 @@ struct rndis_wlan_private { | |||
456 | 465 | ||
457 | /* encryption stuff */ | 466 | /* encryption stuff */ |
458 | int encr_tx_key_index; | 467 | int encr_tx_key_index; |
459 | char encr_keys[4][32]; | 468 | struct rndis_wlan_encr_key encr_keys[4]; |
460 | int encr_key_len[4]; | ||
461 | char encr_key_wpa[4]; | ||
462 | int wpa_version; | 469 | int wpa_version; |
463 | int wpa_keymgmt; | 470 | int wpa_keymgmt; |
464 | int wpa_authalg; | 471 | int wpa_authalg; |
@@ -525,6 +532,15 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv) | |||
525 | } | 532 | } |
526 | 533 | ||
527 | 534 | ||
535 | static bool is_wpa_key(struct rndis_wlan_private *priv, int idx) | ||
536 | { | ||
537 | int cipher = priv->encr_keys[idx].cipher; | ||
538 | |||
539 | return (cipher == WLAN_CIPHER_SUITE_CCMP || | ||
540 | cipher == WLAN_CIPHER_SUITE_TKIP); | ||
541 | } | ||
542 | |||
543 | |||
528 | #ifdef DEBUG | 544 | #ifdef DEBUG |
529 | static const char *oid_to_string(__le32 oid) | 545 | static const char *oid_to_string(__le32 oid) |
530 | { | 546 | { |
@@ -895,8 +911,7 @@ static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig) | |||
895 | /* | 911 | /* |
896 | * common functions | 912 | * common functions |
897 | */ | 913 | */ |
898 | static int | 914 | static void restore_keys(struct usbnet *usbdev); |
899 | add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index); | ||
900 | 915 | ||
901 | static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) | 916 | static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) |
902 | { | 917 | { |
@@ -1115,7 +1130,7 @@ static int set_infra_mode(struct usbnet *usbdev, int mode) | |||
1115 | { | 1130 | { |
1116 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1131 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1117 | __le32 tmp; | 1132 | __le32 tmp; |
1118 | int ret, i; | 1133 | int ret; |
1119 | 1134 | ||
1120 | devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode); | 1135 | devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode); |
1121 | 1136 | ||
@@ -1130,14 +1145,7 @@ static int set_infra_mode(struct usbnet *usbdev, int mode) | |||
1130 | /* NDIS drivers clear keys when infrastructure mode is | 1145 | /* NDIS drivers clear keys when infrastructure mode is |
1131 | * changed. But Linux tools assume otherwise. So set the | 1146 | * changed. But Linux tools assume otherwise. So set the |
1132 | * keys */ | 1147 | * keys */ |
1133 | if (priv->wpa_keymgmt == 0 || | 1148 | restore_keys(usbdev); |
1134 | priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) { | ||
1135 | for (i = 0; i < 4; i++) { | ||
1136 | if (priv->encr_key_len[i] > 0 && !priv->encr_key_wpa[i]) | ||
1137 | add_wep_key(usbdev, priv->encr_keys[i], | ||
1138 | priv->encr_key_len[i], i); | ||
1139 | } | ||
1140 | } | ||
1141 | 1149 | ||
1142 | priv->infra_mode = mode; | 1150 | priv->infra_mode = mode; |
1143 | return 0; | 1151 | return 0; |
@@ -1204,11 +1212,16 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) | |||
1204 | { | 1212 | { |
1205 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1213 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1206 | struct ndis_80211_wep_key ndis_key; | 1214 | struct ndis_80211_wep_key ndis_key; |
1207 | int ret; | 1215 | int cipher, ret; |
1208 | 1216 | ||
1209 | if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4) | 1217 | if ((key_len != 5 || key_len != 13) || index < 0 || index > 3) |
1210 | return -EINVAL; | 1218 | return -EINVAL; |
1211 | 1219 | ||
1220 | if (key_len == 5) | ||
1221 | cipher = WLAN_CIPHER_SUITE_WEP40; | ||
1222 | else | ||
1223 | cipher = WLAN_CIPHER_SUITE_WEP104; | ||
1224 | |||
1212 | memset(&ndis_key, 0, sizeof(ndis_key)); | 1225 | memset(&ndis_key, 0, sizeof(ndis_key)); |
1213 | 1226 | ||
1214 | ndis_key.size = cpu_to_le32(sizeof(ndis_key)); | 1227 | ndis_key.size = cpu_to_le32(sizeof(ndis_key)); |
@@ -1233,30 +1246,44 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) | |||
1233 | return ret; | 1246 | return ret; |
1234 | } | 1247 | } |
1235 | 1248 | ||
1236 | priv->encr_key_len[index] = key_len; | 1249 | priv->encr_keys[index].len = key_len; |
1237 | priv->encr_key_wpa[index] = 0; | 1250 | priv->encr_keys[index].cipher = cipher; |
1238 | memcpy(&priv->encr_keys[index], key, key_len); | 1251 | memcpy(&priv->encr_keys[index].material, key, key_len); |
1252 | memset(&priv->encr_keys[index].bssid, 0xff, ETH_ALEN); | ||
1239 | 1253 | ||
1240 | return 0; | 1254 | return 0; |
1241 | } | 1255 | } |
1242 | 1256 | ||
1243 | 1257 | ||
1244 | static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | 1258 | static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, |
1245 | int index, const struct sockaddr *addr, | 1259 | int index, const u8 *addr, const u8 *rx_seq, int cipher, |
1246 | const u8 *rx_seq, int alg, int flags) | 1260 | int flags) |
1247 | { | 1261 | { |
1248 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1262 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1249 | struct ndis_80211_key ndis_key; | 1263 | struct ndis_80211_key ndis_key; |
1264 | bool is_addr_ok; | ||
1250 | int ret; | 1265 | int ret; |
1251 | 1266 | ||
1252 | if (index < 0 || index >= 4) | 1267 | if (index < 0 || index >= 4) { |
1268 | devdbg(usbdev, "add_wpa_key: index out of range (%i)", index); | ||
1253 | return -EINVAL; | 1269 | return -EINVAL; |
1254 | if (key_len > sizeof(ndis_key.material) || key_len < 0) | 1270 | } |
1271 | if (key_len > sizeof(ndis_key.material) || key_len < 0) { | ||
1272 | devdbg(usbdev, "add_wpa_key: key length out of range (%i)", | ||
1273 | key_len); | ||
1255 | return -EINVAL; | 1274 | return -EINVAL; |
1256 | if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) | 1275 | } |
1276 | if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) { | ||
1277 | devdbg(usbdev, "add_wpa_key: recv seq flag without buffer"); | ||
1257 | return -EINVAL; | 1278 | return -EINVAL; |
1258 | if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr) | 1279 | } |
1280 | is_addr_ok = addr && memcmp(addr, zero_bssid, ETH_ALEN) != 0 && | ||
1281 | memcmp(addr, ffff_bssid, ETH_ALEN) != 0; | ||
1282 | if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !is_addr_ok) { | ||
1283 | devdbg(usbdev, "add_wpa_key: pairwise but bssid invalid (%pM)", | ||
1284 | addr); | ||
1259 | return -EINVAL; | 1285 | return -EINVAL; |
1286 | } | ||
1260 | 1287 | ||
1261 | devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, | 1288 | devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, |
1262 | !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY), | 1289 | !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY), |
@@ -1270,7 +1297,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1270 | ndis_key.length = cpu_to_le32(key_len); | 1297 | ndis_key.length = cpu_to_le32(key_len); |
1271 | ndis_key.index = cpu_to_le32(index) | flags; | 1298 | ndis_key.index = cpu_to_le32(index) | flags; |
1272 | 1299 | ||
1273 | if (alg == IW_ENCODE_ALG_TKIP && key_len == 32) { | 1300 | if (cipher == WLAN_CIPHER_SUITE_TKIP && key_len == 32) { |
1274 | /* wpa_supplicant gives us the Michael MIC RX/TX keys in | 1301 | /* wpa_supplicant gives us the Michael MIC RX/TX keys in |
1275 | * different order than NDIS spec, so swap the order here. */ | 1302 | * different order than NDIS spec, so swap the order here. */ |
1276 | memcpy(ndis_key.material, key, 16); | 1303 | memcpy(ndis_key.material, key, 16); |
@@ -1284,7 +1311,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1284 | 1311 | ||
1285 | if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) { | 1312 | if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) { |
1286 | /* pairwise key */ | 1313 | /* pairwise key */ |
1287 | memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN); | 1314 | memcpy(ndis_key.bssid, addr, ETH_ALEN); |
1288 | } else { | 1315 | } else { |
1289 | /* group key */ | 1316 | /* group key */ |
1290 | if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) | 1317 | if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) |
@@ -1299,8 +1326,14 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1299 | if (ret != 0) | 1326 | if (ret != 0) |
1300 | return ret; | 1327 | return ret; |
1301 | 1328 | ||
1302 | priv->encr_key_len[index] = key_len; | 1329 | memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index])); |
1303 | priv->encr_key_wpa[index] = 1; | 1330 | priv->encr_keys[index].len = key_len; |
1331 | priv->encr_keys[index].cipher = cipher; | ||
1332 | memcpy(&priv->encr_keys[index].material, key, key_len); | ||
1333 | if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) | ||
1334 | memcpy(&priv->encr_keys[index].bssid, ndis_key.bssid, ETH_ALEN); | ||
1335 | else | ||
1336 | memset(&priv->encr_keys[index].bssid, 0xff, ETH_ALEN); | ||
1304 | 1337 | ||
1305 | if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY) | 1338 | if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY) |
1306 | priv->encr_tx_key_index = index; | 1339 | priv->encr_tx_key_index = index; |
@@ -1309,25 +1342,74 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1309 | } | 1342 | } |
1310 | 1343 | ||
1311 | 1344 | ||
1345 | static int restore_key(struct usbnet *usbdev, int key_idx) | ||
1346 | { | ||
1347 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | ||
1348 | struct rndis_wlan_encr_key key; | ||
1349 | int flags; | ||
1350 | |||
1351 | key = priv->encr_keys[key_idx]; | ||
1352 | |||
1353 | devdbg(usbdev, "restore_key: %i:%s:%i", key_idx, | ||
1354 | is_wpa_key(priv, key_idx) ? "wpa" : "wep", | ||
1355 | key.len); | ||
1356 | |||
1357 | if (key.len == 0) | ||
1358 | return 0; | ||
1359 | |||
1360 | if (is_wpa_key(priv, key_idx)) { | ||
1361 | flags = 0; | ||
1362 | |||
1363 | /*if (priv->encr_tx_key_index == key_idx) | ||
1364 | flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;*/ | ||
1365 | |||
1366 | if (memcmp(key.bssid, zero_bssid, ETH_ALEN) != 0 && | ||
1367 | memcmp(key.bssid, ffff_bssid, ETH_ALEN) != 0) | ||
1368 | flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY; | ||
1369 | |||
1370 | return add_wpa_key(usbdev, key.material, key.len, key_idx, | ||
1371 | key.bssid, NULL, key.cipher, flags); | ||
1372 | } | ||
1373 | |||
1374 | return add_wep_key(usbdev, key.material, key.len, key_idx); | ||
1375 | } | ||
1376 | |||
1377 | |||
1378 | static void restore_keys(struct usbnet *usbdev) | ||
1379 | { | ||
1380 | int i; | ||
1381 | |||
1382 | for (i = 0; i < 4; i++) | ||
1383 | restore_key(usbdev, i); | ||
1384 | } | ||
1385 | |||
1386 | |||
1387 | static void clear_key(struct rndis_wlan_private *priv, int idx) | ||
1388 | { | ||
1389 | memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); | ||
1390 | } | ||
1391 | |||
1392 | |||
1312 | /* remove_key is for both wep and wpa */ | 1393 | /* remove_key is for both wep and wpa */ |
1313 | static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | 1394 | static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) |
1314 | { | 1395 | { |
1315 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1396 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1316 | struct ndis_80211_remove_key remove_key; | 1397 | struct ndis_80211_remove_key remove_key; |
1317 | __le32 keyindex; | 1398 | __le32 keyindex; |
1399 | bool is_wpa; | ||
1318 | int ret; | 1400 | int ret; |
1319 | 1401 | ||
1320 | if (priv->encr_key_len[index] == 0) | 1402 | if (priv->encr_keys[index].len == 0) |
1321 | return 0; | 1403 | return 0; |
1322 | 1404 | ||
1323 | priv->encr_key_len[index] = 0; | 1405 | is_wpa = is_wpa_key(priv, index); |
1324 | priv->encr_key_wpa[index] = 0; | ||
1325 | memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index])); | ||
1326 | 1406 | ||
1327 | if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP || | 1407 | devdbg(usbdev, "remove_key: %i:%s:%i", index, is_wpa ? "wpa" : "wep", |
1328 | priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP || | 1408 | priv->encr_keys[index].len); |
1329 | priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP || | 1409 | |
1330 | priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) { | 1410 | clear_key(priv, index); |
1411 | |||
1412 | if (is_wpa) { | ||
1331 | remove_key.size = cpu_to_le32(sizeof(remove_key)); | 1413 | remove_key.size = cpu_to_le32(sizeof(remove_key)); |
1332 | remove_key.index = cpu_to_le32(index); | 1414 | remove_key.index = cpu_to_le32(index); |
1333 | if (bssid) { | 1415 | if (bssid) { |
@@ -1871,8 +1953,9 @@ static int rndis_iw_set_encode(struct net_device *dev, | |||
1871 | { | 1953 | { |
1872 | struct usbnet *usbdev = netdev_priv(dev); | 1954 | struct usbnet *usbdev = netdev_priv(dev); |
1873 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1955 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1956 | struct rndis_wlan_encr_key key; | ||
1874 | int ret, index, key_len; | 1957 | int ret, index, key_len; |
1875 | u8 *key; | 1958 | u8 *keybuf; |
1876 | 1959 | ||
1877 | index = (wrqu->encoding.flags & IW_ENCODE_INDEX); | 1960 | index = (wrqu->encoding.flags & IW_ENCODE_INDEX); |
1878 | 1961 | ||
@@ -1907,17 +1990,18 @@ static int rndis_iw_set_encode(struct net_device *dev, | |||
1907 | 1990 | ||
1908 | if (wrqu->data.length > 0) { | 1991 | if (wrqu->data.length > 0) { |
1909 | key_len = wrqu->data.length; | 1992 | key_len = wrqu->data.length; |
1910 | key = extra; | 1993 | keybuf = extra; |
1911 | } else { | 1994 | } else { |
1912 | /* must be set as tx key */ | 1995 | /* must be set as tx key */ |
1913 | if (priv->encr_key_len[index] == 0) | 1996 | if (priv->encr_keys[index].len == 0) |
1914 | return -EINVAL; | 1997 | return -EINVAL; |
1915 | key_len = priv->encr_key_len[index]; | ||
1916 | key = priv->encr_keys[index]; | 1998 | key = priv->encr_keys[index]; |
1999 | key_len = key.len; | ||
2000 | keybuf = key.material; | ||
1917 | priv->encr_tx_key_index = index; | 2001 | priv->encr_tx_key_index = index; |
1918 | } | 2002 | } |
1919 | 2003 | ||
1920 | if (add_wep_key(usbdev, key, key_len, index) != 0) | 2004 | if (add_wep_key(usbdev, keybuf, key_len, index) != 0) |
1921 | return -EINVAL; | 2005 | return -EINVAL; |
1922 | 2006 | ||
1923 | if (index == priv->encr_tx_key_index) | 2007 | if (index == priv->encr_tx_key_index) |
@@ -1934,7 +2018,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, | |||
1934 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 2018 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
1935 | struct usbnet *usbdev = netdev_priv(dev); | 2019 | struct usbnet *usbdev = netdev_priv(dev); |
1936 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 2020 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1937 | int keyidx, flags; | 2021 | int keyidx, flags, cipher; |
1938 | 2022 | ||
1939 | keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; | 2023 | keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; |
1940 | 2024 | ||
@@ -1944,8 +2028,10 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, | |||
1944 | else | 2028 | else |
1945 | keyidx = priv->encr_tx_key_index; | 2029 | keyidx = priv->encr_tx_key_index; |
1946 | 2030 | ||
1947 | if (keyidx < 0 || keyidx >= 4) | 2031 | if (keyidx < 0 || keyidx >= 4) { |
2032 | devwarn(usbdev, "encryption index out of range (%u)", keyidx); | ||
1948 | return -EINVAL; | 2033 | return -EINVAL; |
2034 | } | ||
1949 | 2035 | ||
1950 | if (ext->alg == WPA_ALG_WEP) { | 2036 | if (ext->alg == WPA_ALG_WEP) { |
1951 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) | 2037 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) |
@@ -1953,10 +2039,19 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, | |||
1953 | return add_wep_key(usbdev, ext->key, ext->key_len, keyidx); | 2039 | return add_wep_key(usbdev, ext->key, ext->key_len, keyidx); |
1954 | } | 2040 | } |
1955 | 2041 | ||
2042 | cipher = -1; | ||
2043 | if (ext->alg == IW_ENCODE_ALG_TKIP) | ||
2044 | cipher = WLAN_CIPHER_SUITE_TKIP; | ||
2045 | else if (ext->alg == IW_ENCODE_ALG_CCMP) | ||
2046 | cipher = WLAN_CIPHER_SUITE_CCMP; | ||
2047 | |||
1956 | if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) || | 2048 | if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) || |
1957 | ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0) | 2049 | ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0) |
1958 | return remove_key(usbdev, keyidx, NULL); | 2050 | return remove_key(usbdev, keyidx, NULL); |
1959 | 2051 | ||
2052 | if (cipher == -1) | ||
2053 | return -EOPNOTSUPP; | ||
2054 | |||
1960 | flags = 0; | 2055 | flags = 0; |
1961 | if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) | 2056 | if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) |
1962 | flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ; | 2057 | flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ; |
@@ -1965,8 +2060,9 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, | |||
1965 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) | 2060 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) |
1966 | flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY; | 2061 | flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY; |
1967 | 2062 | ||
1968 | return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr, | 2063 | return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, |
1969 | ext->rx_seq, ext->alg, flags); | 2064 | (u8 *)&ext->addr.sa_data, ext->rx_seq, cipher, |
2065 | flags); | ||
1970 | } | 2066 | } |
1971 | 2067 | ||
1972 | 2068 | ||