aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rndis_wlan.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2009-08-28 06:27:58 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:58 -0400
commit84bf8400cee127be3b58a9d9b8cfa453dad999ab (patch)
treeafcc0aad6b36636d163c8e5cfae629990846afc2 /drivers/net/wireless/rndis_wlan.c
parent5554adbe0d366f6a5096e6f74b48dcad5698c528 (diff)
rndis_wlan: add cfg80211 key handling
Add cfg80211 add_key/del_key/set_default_key and convert wext to use theim. 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.c133
1 files changed, 103 insertions, 30 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index ffb195dcf4f8..93b504bc2dc5 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -424,7 +424,7 @@ static const u32 rndis_cipher_suites[] = {
424 424
425struct rndis_wlan_encr_key { 425struct rndis_wlan_encr_key {
426 int len; 426 int len;
427 int cipher; 427 u32 cipher;
428 u8 material[32]; 428 u8 material[32];
429 u8 bssid[ETH_ALEN]; 429 u8 bssid[ETH_ALEN];
430 bool pairwise; 430 bool pairwise;
@@ -520,6 +520,16 @@ static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
520static int rndis_set_channel(struct wiphy *wiphy, 520static int rndis_set_channel(struct wiphy *wiphy,
521 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type); 521 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
522 522
523static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
524 u8 key_index, const u8 *mac_addr,
525 struct key_params *params);
526
527static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
528 u8 key_index, const u8 *mac_addr);
529
530static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
531 u8 key_index);
532
523static struct cfg80211_ops rndis_config_ops = { 533static struct cfg80211_ops rndis_config_ops = {
524 .change_virtual_intf = rndis_change_virtual_intf, 534 .change_virtual_intf = rndis_change_virtual_intf,
525 .scan = rndis_scan, 535 .scan = rndis_scan,
@@ -531,6 +541,9 @@ static struct cfg80211_ops rndis_config_ops = {
531 .join_ibss = rndis_join_ibss, 541 .join_ibss = rndis_join_ibss,
532 .leave_ibss = rndis_leave_ibss, 542 .leave_ibss = rndis_leave_ibss,
533 .set_channel = rndis_set_channel, 543 .set_channel = rndis_set_channel,
544 .add_key = rndis_add_key,
545 .del_key = rndis_del_key,
546 .set_default_key = rndis_set_default_key,
534}; 547};
535 548
536static void *rndis_wiphy_privid = &rndis_wiphy_privid; 549static void *rndis_wiphy_privid = &rndis_wiphy_privid;
@@ -1258,7 +1271,10 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
1258{ 1271{
1259 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1272 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1260 struct ndis_80211_wep_key ndis_key; 1273 struct ndis_80211_wep_key ndis_key;
1261 int cipher, ret; 1274 u32 cipher;
1275 int ret;
1276
1277 devdbg(usbdev, "add_wep_key(idx: %d, len: %d)", index, key_len);
1262 1278
1263 if ((key_len != 5 && key_len != 13) || index < 0 || index > 3) 1279 if ((key_len != 5 && key_len != 13) || index < 0 || index > 3)
1264 return -EINVAL; 1280 return -EINVAL;
@@ -1302,8 +1318,8 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
1302 1318
1303 1319
1304static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, 1320static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1305 int index, const u8 *addr, const u8 *rx_seq, int cipher, 1321 int index, const u8 *addr, const u8 *rx_seq,
1306 int flags) 1322 int seq_len, u32 cipher, int flags)
1307{ 1323{
1308 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1324 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1309 struct ndis_80211_key ndis_key; 1325 struct ndis_80211_key ndis_key;
@@ -1319,10 +1335,18 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1319 key_len); 1335 key_len);
1320 return -EINVAL; 1336 return -EINVAL;
1321 } 1337 }
1322 if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) { 1338 if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) {
1323 devdbg(usbdev, "add_wpa_key: recv seq flag without buffer"); 1339 if (!rx_seq || seq_len <= 0) {
1324 return -EINVAL; 1340 devdbg(usbdev, "add_wpa_key: recv seq flag without"
1341 "buffer");
1342 return -EINVAL;
1343 }
1344 if (rx_seq && seq_len > sizeof(ndis_key.rsc)) {
1345 devdbg(usbdev, "add_wpa_key: too big recv seq buffer");
1346 return -EINVAL;
1347 }
1325 } 1348 }
1349
1326 is_addr_ok = addr && !is_zero_ether_addr(addr) && 1350 is_addr_ok = addr && !is_zero_ether_addr(addr) &&
1327 !is_broadcast_ether_addr(addr); 1351 !is_broadcast_ether_addr(addr);
1328 if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !is_addr_ok) { 1352 if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !is_addr_ok) {
@@ -1353,7 +1377,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1353 memcpy(ndis_key.material, key, key_len); 1377 memcpy(ndis_key.material, key, key_len);
1354 1378
1355 if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) 1379 if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)
1356 memcpy(ndis_key.rsc, rx_seq, 6); 1380 memcpy(ndis_key.rsc, rx_seq, seq_len);
1357 1381
1358 if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) { 1382 if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) {
1359 /* pairwise key */ 1383 /* pairwise key */
@@ -1392,31 +1416,17 @@ static int restore_key(struct usbnet *usbdev, int key_idx)
1392{ 1416{
1393 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1417 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1394 struct rndis_wlan_encr_key key; 1418 struct rndis_wlan_encr_key key;
1395 int flags; 1419
1420 if (is_wpa_key(priv, key_idx))
1421 return 0;
1396 1422
1397 key = priv->encr_keys[key_idx]; 1423 key = priv->encr_keys[key_idx];
1398 1424
1399 devdbg(usbdev, "restore_key: %i:%s:%i", key_idx, 1425 devdbg(usbdev, "restore_key: %i:%i", key_idx, key.len);
1400 is_wpa_key(priv, key_idx) ? "wpa" : "wep",
1401 key.len);
1402 1426
1403 if (key.len == 0) 1427 if (key.len == 0)
1404 return 0; 1428 return 0;
1405 1429
1406 if (is_wpa_key(priv, key_idx)) {
1407 flags = 0;
1408
1409 /*if (priv->encr_tx_key_index == key_idx)
1410 flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;*/
1411
1412 if (!is_zero_ether_addr(key.bssid) &&
1413 !is_broadcast_ether_addr(key.bssid))
1414 flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY;
1415
1416 return add_wpa_key(usbdev, key.material, key.len, key_idx,
1417 key.bssid, NULL, key.cipher, flags);
1418 }
1419
1420 return add_wep_key(usbdev, key.material, key.len, key_idx); 1430 return add_wep_key(usbdev, key.material, key.len, key_idx);
1421} 1431}
1422 1432
@@ -1437,7 +1447,7 @@ static void clear_key(struct rndis_wlan_private *priv, int idx)
1437 1447
1438 1448
1439/* remove_key is for both wep and wpa */ 1449/* remove_key is for both wep and wpa */
1440static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) 1450static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
1441{ 1451{
1442 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1452 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1443 struct ndis_80211_remove_key remove_key; 1453 struct ndis_80211_remove_key remove_key;
@@ -2041,6 +2051,69 @@ static int rndis_set_channel(struct wiphy *wiphy,
2041 ieee80211_frequency_to_channel(chan->center_freq)); 2051 ieee80211_frequency_to_channel(chan->center_freq));
2042} 2052}
2043 2053
2054static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
2055 u8 key_index, const u8 *mac_addr,
2056 struct key_params *params)
2057{
2058 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2059 struct usbnet *usbdev = priv->usbdev;
2060 int flags;
2061
2062 devdbg(usbdev, "rndis_add_key(%i, %pM, %08x)", key_index, mac_addr,
2063 params->cipher);
2064
2065 switch (params->cipher) {
2066 case WLAN_CIPHER_SUITE_WEP40:
2067 case WLAN_CIPHER_SUITE_WEP104:
2068 return add_wep_key(usbdev, params->key, params->key_len,
2069 key_index);
2070 case WLAN_CIPHER_SUITE_TKIP:
2071 case WLAN_CIPHER_SUITE_CCMP:
2072 flags = 0;
2073
2074 if (params->seq && params->seq_len > 0)
2075 flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ;
2076 if (mac_addr)
2077 flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY |
2078 NDIS_80211_ADDKEY_TRANSMIT_KEY;
2079
2080 return add_wpa_key(usbdev, params->key, params->key_len,
2081 key_index, mac_addr, params->seq,
2082 params->seq_len, params->cipher, flags);
2083 default:
2084 devdbg(usbdev, "rndis_add_key: unsupported cipher %08x",
2085 params->cipher);
2086 return -ENOTSUPP;
2087 }
2088}
2089
2090static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
2091 u8 key_index, const u8 *mac_addr)
2092{
2093 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2094 struct usbnet *usbdev = priv->usbdev;
2095
2096 devdbg(usbdev, "rndis_del_key(%i, %pM)", key_index, mac_addr);
2097
2098 return remove_key(usbdev, key_index, mac_addr);
2099}
2100
2101static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
2102 u8 key_index)
2103{
2104 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2105 struct usbnet *usbdev = priv->usbdev;
2106 struct rndis_wlan_encr_key key;
2107
2108 devdbg(usbdev, "rndis_set_default_key(%i)", key_index);
2109
2110 priv->encr_tx_key_index = key_index;
2111
2112 key = priv->encr_keys[key_index];
2113
2114 return add_wep_key(usbdev, key.material, key.len, key_index);
2115}
2116
2044/* 2117/*
2045 * wireless extension handlers 2118 * wireless extension handlers
2046 */ 2119 */
@@ -2268,7 +2341,6 @@ static int rndis_iw_get_auth(struct net_device *dev,
2268 } 2341 }
2269 return 0; 2342 return 0;
2270} 2343}
2271#endif
2272 2344
2273 2345
2274static int rndis_iw_set_encode(struct net_device *dev, 2346static int rndis_iw_set_encode(struct net_device *dev,
@@ -2387,6 +2459,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
2387 (u8 *)&ext->addr.sa_data, ext->rx_seq, cipher, 2459 (u8 *)&ext->addr.sa_data, ext->rx_seq, cipher,
2388 flags); 2460 flags);
2389} 2461}
2462#endif
2390 2463
2391 2464
2392static int rndis_iw_get_rate(struct net_device *dev, 2465static int rndis_iw_get_rate(struct net_device *dev,
@@ -2444,8 +2517,8 @@ static const iw_handler rndis_iw_handler[] =
2444 IW_IOCTL(SIOCGIWFRAG) = (iw_handler) cfg80211_wext_giwfrag, 2517 IW_IOCTL(SIOCGIWFRAG) = (iw_handler) cfg80211_wext_giwfrag,
2445 IW_IOCTL(SIOCSIWTXPOW) = (iw_handler) cfg80211_wext_siwtxpower, 2518 IW_IOCTL(SIOCSIWTXPOW) = (iw_handler) cfg80211_wext_siwtxpower,
2446 IW_IOCTL(SIOCGIWTXPOW) = (iw_handler) cfg80211_wext_giwtxpower, 2519 IW_IOCTL(SIOCGIWTXPOW) = (iw_handler) cfg80211_wext_giwtxpower,
2447 IW_IOCTL(SIOCSIWENCODE) = rndis_iw_set_encode, 2520 IW_IOCTL(SIOCSIWENCODE) = (iw_handler) cfg80211_wext_siwencode,
2448 IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext, 2521 IW_IOCTL(SIOCSIWENCODEEXT) = (iw_handler) cfg80211_wext_siwencodeext,
2449 IW_IOCTL(SIOCSIWAUTH) = (iw_handler) cfg80211_wext_siwauth, 2522 IW_IOCTL(SIOCSIWAUTH) = (iw_handler) cfg80211_wext_siwauth,
2450 IW_IOCTL(SIOCGIWAUTH) = (iw_handler) cfg80211_wext_giwauth, 2523 IW_IOCTL(SIOCGIWAUTH) = (iw_handler) cfg80211_wext_giwauth,
2451 IW_IOCTL(SIOCSIWGENIE) = (iw_handler) cfg80211_wext_siwgenie, 2524 IW_IOCTL(SIOCSIWGENIE) = (iw_handler) cfg80211_wext_siwgenie,