mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
BACKPORT: cfg80211: Support key configuration for Beacon protection (BIGTK)
IEEE P802.11-REVmd/D3.0 adds support for protecting Beacon frames using a new set of keys (BIGTK; key index 6..7) similarly to the way group-addressed Robust Management frames are protected (IGTK; key index 4..5). Extend cfg80211 and nl80211 to allow the new BIGTK to be configured. Add an extended feature flag to indicate driver support for the new key index values to avoid array overflows in driver implementations and also to indicate to user space when this functionality is available. Bug: 154782456 Signed-off-by: Jouni Malinen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Johannes Berg <[email protected]> Change-Id: I108164b597c46d0f94fc44cbb030cb8c5cd21773 (cherry picked from commit 56be393fa8b40db2d4f54f97614f645eb8d3c32e) Signed-off-by: Vamsi Krishna <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
parent
c971963639
commit
02d9f7e316
7 changed files with 102 additions and 14 deletions
|
|
@ -368,7 +368,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
|
||||
[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
|
||||
.len = WLAN_MAX_KEY_LEN },
|
||||
[NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 5),
|
||||
[NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
|
||||
[NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
|
||||
|
|
@ -1037,7 +1037,7 @@ struct key_parse {
|
|||
struct key_params p;
|
||||
int idx;
|
||||
int type;
|
||||
bool def, defmgmt;
|
||||
bool def, defmgmt, defbeacon;
|
||||
bool def_uni, def_multi;
|
||||
};
|
||||
|
||||
|
|
@ -1053,12 +1053,13 @@ static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
|
|||
|
||||
k->def = !!tb[NL80211_KEY_DEFAULT];
|
||||
k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
|
||||
k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
|
||||
|
||||
if (k->def) {
|
||||
k->def_uni = true;
|
||||
k->def_multi = true;
|
||||
}
|
||||
if (k->defmgmt)
|
||||
if (k->defmgmt || k->defbeacon)
|
||||
k->def_multi = true;
|
||||
|
||||
if (tb[NL80211_KEY_IDX])
|
||||
|
|
@ -1165,14 +1166,17 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (k->def && k->defmgmt) {
|
||||
GENL_SET_ERR_MSG(info, "key with def && defmgmt is invalid");
|
||||
if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
|
||||
(k->defbeacon ? 1 : 0) > 1) {
|
||||
GENL_SET_ERR_MSG(info,
|
||||
"key with multiple default flags is invalid");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (k->defmgmt) {
|
||||
if (k->defmgmt || k->defbeacon) {
|
||||
if (k->def_uni || !k->def_multi) {
|
||||
GENL_SET_ERR_MSG(info, "defmgmt key must be mcast");
|
||||
GENL_SET_ERR_MSG(info,
|
||||
"defmgmt/defbeacon key must be mcast");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1184,14 +1188,20 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
|
|||
"defmgmt key idx not 4 or 5");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (k->defbeacon) {
|
||||
if (k->idx < 6 || k->idx > 7) {
|
||||
GENL_SET_ERR_MSG(info,
|
||||
"defbeacon key idx not 6 or 7");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (k->def) {
|
||||
if (k->idx < 0 || k->idx > 3) {
|
||||
GENL_SET_ERR_MSG(info, "def key idx not 0-3");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (k->idx < 0 || k->idx > 5) {
|
||||
GENL_SET_ERR_MSG(info, "key idx not 0-5");
|
||||
if (k->idx < 0 || k->idx > 7) {
|
||||
GENL_SET_ERR_MSG(info, "key idx not 0-7");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
@ -3817,8 +3827,14 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
|
|||
void *hdr;
|
||||
struct sk_buff *msg;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_KEY_IDX])
|
||||
if (info->attrs[NL80211_ATTR_KEY_IDX]) {
|
||||
key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
|
||||
if (key_idx > 5 &&
|
||||
!wiphy_ext_feature_isset(
|
||||
&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_MAC])
|
||||
mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
|
|
@ -3894,7 +3910,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
|
|||
/* Only support setting default key and
|
||||
* Extended Key ID action NL80211_KEY_SET_TX.
|
||||
*/
|
||||
if (!key.def && !key.defmgmt &&
|
||||
if (!key.def && !key.defmgmt && !key.defbeacon &&
|
||||
!(key.p.mode == NL80211_KEY_SET_TX))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -3941,6 +3957,24 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
|
|||
#ifdef CONFIG_CFG80211_WEXT
|
||||
dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
|
||||
#endif
|
||||
} else if (key.defbeacon) {
|
||||
if (key.def_uni || !key.def_multi) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rdev->ops->set_default_beacon_key) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = nl80211_key_allowed(dev->ieee80211_ptr);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = rdev_set_default_beacon_key(rdev, dev, key.idx);
|
||||
if (err)
|
||||
goto out;
|
||||
} else if (key.p.mode == NL80211_KEY_SET_TX &&
|
||||
wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_EXT_KEY_ID)) {
|
||||
|
|
|
|||
|
|
@ -136,6 +136,19 @@ rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, u8 key_index)
|
||||
{
|
||||
int ret;
|
||||
|
||||
trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, key_index);
|
||||
ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev,
|
||||
key_index);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int rdev_start_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_ap_settings *settings)
|
||||
|
|
|
|||
|
|
@ -1111,9 +1111,16 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
|
|||
* Delete all the keys ... pairwise keys can't really
|
||||
* exist any more anyway, but default keys might.
|
||||
*/
|
||||
if (rdev->ops->del_key)
|
||||
for (i = 0; i < 6; i++)
|
||||
if (rdev->ops->del_key) {
|
||||
int max_key_idx = 5;
|
||||
|
||||
if (wiphy_ext_feature_isset(
|
||||
wdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION))
|
||||
max_key_idx = 7;
|
||||
for (i = 0; i <= max_key_idx; i++)
|
||||
rdev_del_key(rdev, dev, i, false, NULL);
|
||||
}
|
||||
|
||||
rdev_set_qos_map(rdev, dev, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -510,6 +510,23 @@ TRACE_EVENT(rdev_set_default_mgmt_key,
|
|||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_set_default_beacon_key,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index),
|
||||
TP_ARGS(wiphy, netdev, key_index),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
__field(u8, key_index)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
__entry->key_index = key_index;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_start_ap,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct cfg80211_ap_settings *settings),
|
||||
|
|
|
|||
|
|
@ -231,7 +231,12 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
|
|||
struct key_params *params, int key_idx,
|
||||
bool pairwise, const u8 *mac_addr)
|
||||
{
|
||||
if (key_idx < 0 || key_idx > 5)
|
||||
int max_key_idx = 5;
|
||||
|
||||
if (wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION))
|
||||
max_key_idx = 7;
|
||||
if (key_idx < 0 || key_idx > max_key_idx)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
|
||||
|
|
|
|||
Loading…
Reference in a new issue