aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rndis_wlan.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2009-05-22 10:40:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-22 14:06:03 -0400
commitb145ee0ce1e325497e5bb91f78f1545b552b518f (patch)
tree4006659d43aef6e6c3947fed8cee93e805d037aa /drivers/net/wireless/rndis_wlan.c
parentb4703a2e32fdffbf83caf699817b21c4fc6d987c (diff)
rndis_wlan: split add_wpa_key from rndis_iw_set_encode_ext
Split add_wpa_key() from rndis_iw_set_encode_ext so that conversion to cfg80211 would be easier later on. 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.c129
1 files changed, 76 insertions, 53 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 041680019a8e..98f6ff753d61 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -1033,6 +1033,73 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
1033} 1033}
1034 1034
1035 1035
1036static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1037 int index, const struct sockaddr *addr,
1038 const u8 *rx_seq, int alg, int flags)
1039{
1040 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1041 struct ndis_80211_key ndis_key;
1042 int ret;
1043
1044 if (index < 0 || index >= 4)
1045 return -EINVAL;
1046 if (key_len > sizeof(ndis_key.material) || key_len < 0)
1047 return -EINVAL;
1048 if ((flags & ndis_80211_addkey_set_init_recv_seq) && !rx_seq)
1049 return -EINVAL;
1050 if ((flags & ndis_80211_addkey_pairwise_key) && !addr)
1051 return -EINVAL;
1052
1053 devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index,
1054 !!(flags & ndis_80211_addkey_transmit_key),
1055 !!(flags & ndis_80211_addkey_pairwise_key),
1056 !!(flags & ndis_80211_addkey_set_init_recv_seq));
1057
1058 memset(&ndis_key, 0, sizeof(ndis_key));
1059
1060 ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
1061 sizeof(ndis_key.material) + key_len);
1062 ndis_key.length = cpu_to_le32(key_len);
1063 ndis_key.index = cpu_to_le32(index) | flags;
1064
1065 if (alg == IW_ENCODE_ALG_TKIP && key_len == 32) {
1066 /* wpa_supplicant gives us the Michael MIC RX/TX keys in
1067 * different order than NDIS spec, so swap the order here. */
1068 memcpy(ndis_key.material, key, 16);
1069 memcpy(ndis_key.material + 16, key + 24, 8);
1070 memcpy(ndis_key.material + 24, key + 16, 8);
1071 } else
1072 memcpy(ndis_key.material, key, key_len);
1073
1074 if (flags & ndis_80211_addkey_set_init_recv_seq)
1075 memcpy(ndis_key.rsc, rx_seq, 6);
1076
1077 if (flags & ndis_80211_addkey_pairwise_key) {
1078 /* pairwise key */
1079 memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN);
1080 } else {
1081 /* group key */
1082 if (priv->infra_mode == ndis_80211_infra_adhoc)
1083 memset(ndis_key.bssid, 0xff, ETH_ALEN);
1084 else
1085 get_bssid(usbdev, ndis_key.bssid);
1086 }
1087
1088 ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
1089 le32_to_cpu(ndis_key.size));
1090 devdbg(usbdev, "add_wpa_key: OID_802_11_ADD_KEY -> %08X", ret);
1091 if (ret != 0)
1092 return ret;
1093
1094 priv->encr_key_len[index] = key_len;
1095 memcpy(&priv->encr_keys[index], ndis_key.material, key_len);
1096 if (flags & ndis_80211_addkey_transmit_key)
1097 priv->encr_tx_key_index = index;
1098
1099 return 0;
1100}
1101
1102
1036/* remove_key is for both wep and wpa */ 1103/* remove_key is for both wep and wpa */
1037static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) 1104static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
1038{ 1105{
@@ -1602,9 +1669,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
1602 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 1669 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1603 struct usbnet *usbdev = netdev_priv(dev); 1670 struct usbnet *usbdev = netdev_priv(dev);
1604 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1671 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1605 struct ndis_80211_key ndis_key; 1672 int keyidx, flags;
1606 int keyidx, ret;
1607 u8 *addr;
1608 1673
1609 keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; 1674 keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
1610 1675
@@ -1627,58 +1692,16 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
1627 ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0) 1692 ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
1628 return remove_key(usbdev, keyidx, NULL); 1693 return remove_key(usbdev, keyidx, NULL);
1629 1694
1630 if (ext->key_len > sizeof(ndis_key.material)) 1695 flags = 0;
1631 return -1; 1696 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1632 1697 flags |= ndis_80211_addkey_set_init_recv_seq;
1633 memset(&ndis_key, 0, sizeof(ndis_key)); 1698 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
1634 1699 flags |= ndis_80211_addkey_pairwise_key;
1635 ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
1636 sizeof(ndis_key.material) + ext->key_len);
1637 ndis_key.length = cpu_to_le32(ext->key_len);
1638 ndis_key.index = cpu_to_le32(keyidx);
1639
1640 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1641 memcpy(ndis_key.rsc, ext->rx_seq, 6);
1642 ndis_key.index |= ndis_80211_addkey_set_init_recv_seq;
1643 }
1644
1645 addr = ext->addr.sa_data;
1646 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1647 /* group key */
1648 if (priv->infra_mode == ndis_80211_infra_adhoc)
1649 memset(ndis_key.bssid, 0xff, ETH_ALEN);
1650 else
1651 get_bssid(usbdev, ndis_key.bssid);
1652 } else {
1653 /* pairwise key */
1654 ndis_key.index |= ndis_80211_addkey_pairwise_key;
1655 memcpy(ndis_key.bssid, addr, ETH_ALEN);
1656 }
1657
1658 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 1700 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1659 ndis_key.index |= ndis_80211_addkey_transmit_key; 1701 flags |= ndis_80211_addkey_transmit_key;
1660
1661 if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
1662 /* wpa_supplicant gives us the Michael MIC RX/TX keys in
1663 * different order than NDIS spec, so swap the order here. */
1664 memcpy(ndis_key.material, ext->key, 16);
1665 memcpy(ndis_key.material + 16, ext->key + 24, 8);
1666 memcpy(ndis_key.material + 24, ext->key + 16, 8);
1667 } else
1668 memcpy(ndis_key.material, ext->key, ext->key_len);
1669 1702
1670 ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key, 1703 return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr,
1671 le32_to_cpu(ndis_key.size)); 1704 ext->rx_seq, ext->alg, flags);
1672 devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
1673 if (ret != 0)
1674 return ret;
1675
1676 priv->encr_key_len[keyidx] = ext->key_len;
1677 memcpy(&priv->encr_keys[keyidx], ndis_key.material, ext->key_len);
1678 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1679 priv->encr_tx_key_index = keyidx;
1680
1681 return 0;
1682} 1705}
1683 1706
1684 1707