diff mbox series

[v3,07/17] nl80211: Switch to the new key_type API & cleanup

Message ID 20190817211435.158335-8-alexander@wetzel-home.de
State Superseded
Headers show
Series Support seamless PTK rekeys with Extended Key ID | expand

Commit Message

Alexander Wetzel Aug. 17, 2019, 9:14 p.m. UTC
Installing WEP and broadcast keys require an additional netlink call
with NL80211_CMD_SET_KEY after key install. wpa_driver_nl80211_set_key()
had a overly complex and not always correctly working method to detect
and make this call, heavily depending on the inconsistently set boolean
set_tx. But nl80211 can deduce the information when to call
NL80211_CMD_SET_KEY without referring to the unreliable set boolean
set_tx.
Therefore stop using set_tx and throw out the workarounds used to
suppress some of the needless NL80211_CMD_SET_KEY calls and only call it
when really needed.

This also stops useless NL80211_CMD_SET_KEY calls when installing a
unicast key in wpa_supplicant, which also has set_tx set set to true and
was not intercepted by the workarounds.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
---

This simply was too big to put into the generic patch to migrate the
drivers to key_type. Nl80211 ist the driver with the most features and
also the strangest hacks...  This patch not only migrating to key_type,
it's also overhauling the key install logic.

The new logic works fine for all test cases and to my best understanding
all dropped code pieces could not have any functions. (Verified against
the kernel code.)

 src/drivers/driver_nl80211.c | 56 +++++++++++++++---------------------
 1 file changed, 23 insertions(+), 33 deletions(-)
diff mbox series

Patch

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 3a35a5337..3762e9d66 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -3018,8 +3018,9 @@  static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
 	int ifindex;
 	struct nl_msg *msg;
 	struct nl_msg *key_msg;
+	struct nlattr *types;
+	int need_set_key = 0;
 	int ret;
-	int tdls = 0;
 
 	/* Ignore for P2P Device */
 	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
@@ -3027,13 +3028,12 @@  static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
 
 	ifindex = if_nametoindex(ifname);
 	wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
-		   "set_tx=%d seq_len=%lu key_len=%lu",
+		   "set_tx=%d seq_len=%lu key_len=%lu key_type=%d",
 		   __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
-		   (unsigned long) seq_len, (unsigned long) key_len);
+		   (unsigned long) seq_len, (unsigned long) key_len, key_type);
 #ifdef CONFIG_TDLS
 	if (key_idx == -1) {
 		key_idx = 0;
-		tdls = 1;
 	}
 #endif /* CONFIG_TDLS */
 
@@ -3085,22 +3085,18 @@  static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
 		if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
 			goto fail;
 
-		if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
+		if (alg != WPA_ALG_WEP && key_type != KEY_TYPE_PAIRWISE) {
 			wpa_printf(MSG_DEBUG, "   RSN IBSS RX GTK");
 			if (nla_put_u32(key_msg, NL80211_KEY_TYPE,
 					NL80211_KEYTYPE_GROUP))
 				goto fail;
 		}
-	} else if (addr && is_broadcast_ether_addr(addr)) {
-		struct nlattr *types;
-
-		wpa_printf(MSG_DEBUG, "   broadcast key");
-
-		types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES);
-		if (!types ||
-		    nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
-			goto fail;
-		nla_nest_end(key_msg, types);
+	} else if (alg != WPA_ALG_NONE) {
+		/* Default (WEP, GTK or IGTK) key */
+		if (alg != WPA_ALG_WEP || key_type == KEY_TYPE_DEFAULT) {
+			wpa_printf(MSG_DEBUG, "   require SET_KEY");
+			need_set_key = 1;
+		}
 	}
 	if (nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) ||
 	    nla_put_nested(msg, NL80211_ATTR_KEY, key_msg))
@@ -3114,13 +3110,10 @@  static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
 			   ret, strerror(-ret));
 
 	/*
-	 * If we failed or don't need to set the default TX key (below),
+	 * If we failed or don't need to set the key as default (below),
 	 * we're done here.
 	 */
-	if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
-		return ret;
-	if (is_ap_interface(drv->nlmode) && addr &&
-	    !is_broadcast_ether_addr(addr))
+	if (ret || !need_set_key)
 		return ret;
 
 	key_msg = nlmsg_alloc();
@@ -3140,29 +3133,26 @@  static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
 				   NL80211_KEY_DEFAULT))
 		goto fail;
 	if (addr && is_broadcast_ether_addr(addr)) {
-		struct nlattr *types;
-
+		wpa_printf(MSG_DEBUG, "   broadcast key");
 		types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES);
 		if (!types ||
 		    nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
 			goto fail;
 		nla_nest_end(key_msg, types);
-	} else if (addr) {
-		struct nlattr *types;
-
-		types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES);
-		if (!types ||
-		    nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_UNICAST))
-			goto fail;
-		nla_nest_end(key_msg, types);
+	} else if (!addr) {
+		wpa_printf(MSG_DEBUG, "   WEP key");
+	} else {
+		/* need_set_key must only be set for
+		 * zero or broadcast addresses
+		 */
+		wpa_printf(MSG_ERROR,
+			   "Unicast key when not expecting one, abort!");
+		goto fail;
 	}
 
 	if (nla_put_nested(msg, NL80211_ATTR_KEY, key_msg))
 		goto fail;
-
 	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
-	if (ret == -ENOENT)
-		ret = 0;
 	if (ret)
 		wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
 			   "err=%d %s)", ret, strerror(-ret));