mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
cfg80211: support 4-way handshake offloading for 802.1X
Add API for setting the PMK to the driver. For FT support, allow setting also the PMK-R0 Name. This can be used by drivers that support 4-Way handshake offload while IEEE802.1X authentication is managed by upper layers. Signed-off-by: Avraham Stern <[email protected]> Signed-off-by: Johannes Berg <[email protected]> [[email protected]: add WANT_1X_4WAY_HS attribute] Signed-off-by: Arend van Spriel <[email protected]> [reword NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X docs a bit to say that the device may require it] Signed-off-by: Johannes Berg <[email protected]>
This commit is contained in:
parent
91b5ab6289
commit
3a00df5707
7 changed files with 268 additions and 1 deletions
|
|
@ -711,6 +711,11 @@ int wiphy_register(struct wiphy *wiphy)
|
|||
(wiphy->bss_select_support & ~(BIT(__NL80211_BSS_SELECT_ATTR_AFTER_LAST) - 2))))
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X) &&
|
||||
(!rdev->ops->set_pmk || !rdev->ops->del_pmk)))
|
||||
return -EINVAL;
|
||||
|
||||
if (wiphy->addresses)
|
||||
memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
|
||||
|
||||
|
|
|
|||
|
|
@ -8881,6 +8881,12 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
|
||||
!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
|
||||
return -EINVAL;
|
||||
connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
|
||||
|
||||
err = nl80211_crypto_settings(rdev, info, &connect.crypto,
|
||||
NL80211_MAX_NR_CIPHER_SUITES);
|
||||
if (err)
|
||||
|
|
@ -12265,6 +12271,90 @@ static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
|
|||
return rdev_set_multicast_to_unicast(rdev, dev, enabled);
|
||||
}
|
||||
|
||||
static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_pmk_conf pmk_conf = {};
|
||||
int ret;
|
||||
|
||||
if (wdev->iftype != NL80211_IFTYPE_STATION &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
|
||||
return -EINVAL;
|
||||
|
||||
wdev_lock(wdev);
|
||||
if (!wdev->current_bss) {
|
||||
ret = -ENOTCONN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
|
||||
pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
|
||||
if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
|
||||
pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_PMKR0_NAME]) {
|
||||
int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
|
||||
|
||||
if (r0_name_len != WLAN_PMK_NAME_LEN) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pmk_conf.pmk_r0_name =
|
||||
nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
|
||||
}
|
||||
|
||||
ret = rdev_set_pmk(rdev, dev, &pmk_conf);
|
||||
out:
|
||||
wdev_unlock(wdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
const u8 *aa;
|
||||
int ret;
|
||||
|
||||
if (wdev->iftype != NL80211_IFTYPE_STATION &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_MAC])
|
||||
return -EINVAL;
|
||||
|
||||
wdev_lock(wdev);
|
||||
aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
ret = rdev_del_pmk(rdev, dev, aa);
|
||||
wdev_unlock(wdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define NL80211_FLAG_NEED_WIPHY 0x01
|
||||
#define NL80211_FLAG_NEED_NETDEV 0x02
|
||||
#define NL80211_FLAG_NEED_RTNL 0x04
|
||||
|
|
@ -13140,6 +13230,21 @@ static const struct genl_ops nl80211_ops[] = {
|
|||
.internal_flags = NL80211_FLAG_NEED_NETDEV |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_SET_PMK,
|
||||
.doit = nl80211_set_pmk,
|
||||
.policy = nl80211_policy,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_DEL_PMK,
|
||||
.doit = nl80211_del_pmk,
|
||||
.policy = nl80211_policy,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static struct genl_family nl80211_fam __ro_after_init = {
|
||||
|
|
|
|||
|
|
@ -1164,4 +1164,29 @@ rdev_set_coalesce(struct cfg80211_registered_device *rdev,
|
|||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int rdev_set_pmk(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_pmk_conf *pmk_conf)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
trace_rdev_set_pmk(&rdev->wiphy, dev, pmk_conf);
|
||||
if (rdev->ops->set_pmk)
|
||||
ret = rdev->ops->set_pmk(&rdev->wiphy, dev, pmk_conf);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, const u8 *aa)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
trace_rdev_del_pmk(&rdev->wiphy, dev, aa);
|
||||
if (rdev->ops->del_pmk)
|
||||
ret = rdev->ops->del_pmk(&rdev->wiphy, dev, aa);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* __CFG80211_RDEV_OPS */
|
||||
|
|
|
|||
|
|
@ -2258,6 +2258,66 @@ TRACE_EVENT(rdev_tdls_cancel_channel_switch,
|
|||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr))
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_set_pmk,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct cfg80211_pmk_conf *pmk_conf),
|
||||
|
||||
TP_ARGS(wiphy, netdev, pmk_conf),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
MAC_ENTRY(aa)
|
||||
__field(u8, pmk_len)
|
||||
__field(u8, pmk_r0_name_len)
|
||||
__dynamic_array(u8, pmk, pmk_conf->pmk_len)
|
||||
__dynamic_array(u8, pmk_r0_name, WLAN_PMK_NAME_LEN)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(aa, pmk_conf->aa);
|
||||
__entry->pmk_len = pmk_conf->pmk_len;
|
||||
__entry->pmk_r0_name_len =
|
||||
pmk_conf->pmk_r0_name ? WLAN_PMK_NAME_LEN : 0;
|
||||
memcpy(__get_dynamic_array(pmk), pmk_conf->pmk,
|
||||
pmk_conf->pmk_len);
|
||||
memcpy(__get_dynamic_array(pmk_r0_name), pmk_conf->pmk_r0_name,
|
||||
pmk_conf->pmk_r0_name ? WLAN_PMK_NAME_LEN : 0);
|
||||
),
|
||||
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT
|
||||
"pmk_len=%u, pmk: %s pmk_r0_name: %s", WIPHY_PR_ARG,
|
||||
NETDEV_PR_ARG, MAC_PR_ARG(aa), __entry->pmk_len,
|
||||
__print_array(__get_dynamic_array(pmk),
|
||||
__get_dynamic_array_len(pmk), 1),
|
||||
__entry->pmk_r0_name_len ?
|
||||
__print_array(__get_dynamic_array(pmk_r0_name),
|
||||
__get_dynamic_array_len(pmk_r0_name), 1) : "")
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_del_pmk,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *aa),
|
||||
|
||||
TP_ARGS(wiphy, netdev, aa),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
MAC_ENTRY(aa)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(aa, aa);
|
||||
),
|
||||
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa))
|
||||
);
|
||||
|
||||
/*************************************************************
|
||||
* cfg80211 exported functions traces *
|
||||
*************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in a new issue