Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2be070a authored by Jouni Malinen's avatar Jouni Malinen Committed by Vinita S. Maloo
Browse files

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.

Signed-off-by: default avatarJouni Malinen <jouni@codeaurora.org>
Link: https://lore.kernel.org/r/20200222132548.20835-2-jouni@codeaurora.org


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Git-repo : git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


Git-commit: 56be393fa8b40db2d4f54f97614f645eb8d3c32e
CRs-Fixed: 2641418
Change-Id: I83013d9d56c939d4154d6e7adb3420d5661bd947
Signed-off-by: default avatarVinita S. Maloo <vmaloo@codeaurora.org>
parent e391b118
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@
/* Indicate support for including KEK length in rekey data */
#define CFG80211_REKEY_DATA_KEK_LEN 1

/* Indicate backport support for key configuration for Beacon protection*/
#define CFG80211_BIGTK_CONFIGURATION_SUPPORT 1

/**
 * Indicate backport support for the new cfg80211_roamed event which unifies the
 * old APIs cfg80211_roamed and cfg80211_roamed_bss and takes a structure to
@@ -2688,6 +2691,8 @@ struct cfg80211_update_owe_info {
 * @set_default_key: set the default key on an interface
 *
 * @set_default_mgmt_key: set the default management frame key on an interface

 * @set_default_beacon_key: set the default Beacon frame key on an interface
 *
 * @set_rekey_data: give the data necessary for GTK rekeying to the driver
 *
@@ -2991,6 +2996,9 @@ struct cfg80211_ops {
	int	(*set_default_mgmt_key)(struct wiphy *wiphy,
					struct net_device *netdev,
					u8 key_index);
	int	(*set_default_beacon_key)(struct wiphy *wiphy,
					  struct net_device *netdev,
					  u8 key_index);

	int	(*start_ap)(struct wiphy *wiphy, struct net_device *dev,
			    struct cfg80211_ap_settings *settings);
+33 −0
Original line number Diff line number Diff line
@@ -4164,6 +4164,10 @@ enum nl80211_key_default_types {
 * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags
 *	attributes, specifying what a key should be set as default as.
 *	See &enum nl80211_key_default_types.
 * @NL80211_KEY_MODE: the mode from enum nl80211_key_mode.
 *	Defaults to @NL80211_KEY_RX_TX.
 * @NL80211_KEY_DEFAULT_BEACON: flag indicating default Beacon frame key
 *
 * @__NL80211_KEY_AFTER_LAST: internal
 * @NL80211_KEY_MAX: highest key attribute
 */
@@ -4177,6 +4181,8 @@ enum nl80211_key_attributes {
	NL80211_KEY_DEFAULT_MGMT,
	NL80211_KEY_TYPE,
	NL80211_KEY_DEFAULT_TYPES,
	NL80211_KEY_MODE,
	NL80211_KEY_DEFAULT_BEACON,

	/* keep last */
	__NL80211_KEY_AFTER_LAST,
@@ -5125,6 +5131,26 @@ enum nl80211_feature_flags {
 * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching
 *	(set/del PMKSA operations) in AP mode.
 *
 * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports
 *	filtering of sched scan results using band specific RSSI thresholds.
 *
 * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
 *	to a station.
 *
 * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
 *	station mode (SAE password is passed as part of the connect command).
 *
 * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev
 *	with VLAN tagged frames and separate VLAN-specific netdevs added using
 *	vconfig similarly to the Ethernet case.
 *
 * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
 *	feature, which prevents bufferbloat by using the expected transmission
 *	time to limit the amount of data buffered in the hardware.
 *
 * @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection
 *	and can receive key configuration for BIGTK using key indexes 6 and 7.
 *
 * @NUM_NL80211_EXT_FEATURES: number of extended features.
 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
 */
@@ -5164,6 +5190,13 @@ enum nl80211_ext_feature_index {
	NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
	NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
	NL80211_EXT_FEATURE_AP_PMKSA_CACHING,
	NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
	NL80211_EXT_FEATURE_EXT_KEY_ID,
	NL80211_EXT_FEATURE_STA_TX_PWR,
	NL80211_EXT_FEATURE_SAE_OFFLOAD,
	NL80211_EXT_FEATURE_VLAN_OFFLOAD,
	NL80211_EXT_FEATURE_AQL,
	NL80211_EXT_FEATURE_BEACON_PROTECTION,

	/* add new features before the definition below */
	NUM_NL80211_EXT_FEATURES,
+36 −8
Original line number Diff line number Diff line
@@ -779,7 +779,7 @@ struct key_parse {
	struct key_params p;
	int idx;
	int type;
	bool def, defmgmt;
	bool def, defmgmt, defbeacon;
	bool def_uni, def_multi;
};

@@ -793,12 +793,13 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)

	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])
@@ -905,10 +906,11 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
	if (err)
		return err;

	if (k->def && k->defmgmt)
	if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
	    (k->defbeacon ? 1 : 0) > 1)
		return -EINVAL;

	if (k->defmgmt) {
	if (k->defmgmt || k->defbeacon) {
		if (k->def_uni || !k->def_multi)
			return -EINVAL;
	}
@@ -917,11 +919,14 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
		if (k->defmgmt) {
			if (k->idx < 4 || k->idx > 5)
				return -EINVAL;
		} else if (k->defbeacon) {
			if (k->idx < 6 || k->idx > 7)
				return -EINVAL;
		} else if (k->def) {
			if (k->idx < 0 || k->idx > 3)
				return -EINVAL;
		} else {
			if (k->idx < 0 || k->idx > 5)
			if (k->idx < 0 || k->idx > 7)
				return -EINVAL;
		}
	}
@@ -3162,10 +3167,15 @@ 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 (key_idx > 5)
	if (key_idx > 7)
		return -EINVAL;

	if (info->attrs[NL80211_ATTR_MAC])
@@ -3242,7 +3252,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
		return -EINVAL;

	/* only support setting default key */
	if (!key.def && !key.defmgmt)
	if (!key.def && !key.defmgmt && !key.defbeacon)
		return -EINVAL;

	wdev_lock(dev->ieee80211_ptr);
@@ -3266,6 +3276,24 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
#ifdef CONFIG_CFG80211_WEXT
		dev->ieee80211_ptr->wext.default_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.def_uni || !key.def_multi) {
			err = -EINVAL;
+13 −0
Original line number Diff line number Diff line
@@ -135,6 +135,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)
+9 −2
Original line number Diff line number Diff line
@@ -1027,9 +1027,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);

Loading