diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2009-05-22 10:40:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-22 14:06:03 -0400 |
commit | b145ee0ce1e325497e5bb91f78f1545b552b518f (patch) | |
tree | 4006659d43aef6e6c3947fed8cee93e805d037aa /drivers/net/wireless/rndis_wlan.c | |
parent | b4703a2e32fdffbf83caf699817b21c4fc6d987c (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.c | 129 |
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 | ||
1036 | static 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 */ |
1037 | static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | 1104 | static 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 | ||