Cumulative patch from commit 01a025937c67f0eca6021d94b8ec3b144f8b1730

01a0259 WPS: Add support for 60 GHz band
0ef1e29 WPS: Fix shorter authentication timeout during no-SelReg iteration
3465176 nl80211: Verify that cipher suite conversion succeeds
a250722 Try to set PMK only with key mgmt offload support in the driver
4a7ce98 Make IPv6 NA multicast-to-unicast conversion configurable
9f390f4 Interworking: Fix network selection warning without SIM/USIM support
a0ad9e8 Remove WPA per-VLAN groups when no more stations remain
87b5b53 Make VLAN ID available in STA info over control interface
5678a2d P2P: Allow wpa_supplicant to start if social channels are not supported
209214b vlan: Move CONFIG_FULL_DYNAMIC_VLAN includes to proper places
a6da824 Do not use C++ reserved words as variable names
eaa3728 wpa_gui: Themed icon loader
9a3cb41 Fix wpa_priv (CONFIG_PRIVSEP=y) build
8b423ed Declare all read only data structures as const
fd4fb28 OpenSSL: Try to ensure we don't throw away the PIN unnecessarily
fabc6dd mesh: Retransmit the last Commit Message in the Committed state
068669f vlan: Verify RADIUS returned VLAN-ID and dynamic_vlan=required
5add410 WPS: Use shorter authentication timeout during no-SelReg iteration
e7d2034 WPS: Enforce five second minimum time before AP iteration
bd143cc Remove trailing whitespace from Makefile
74802c0 P2P: Do not create a P2P Device interface if P2P is disabled
579674e Document p2p_disabled option in wpa_supplicant.conf
8ea8a89 nl80211: Extend unique MAC address assignment for station iftype

Change-Id: I8bc8a63f37c0892b83376b9d5a5859827ae50554
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index be0e7c5..26e4984 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -2501,7 +2501,7 @@
 {
 	struct wpa_driver_nl80211_data *drv = bss->drv;
 	int ifindex;
-	struct nl_msg *msg;
+	struct nl_msg *msg = NULL;
 	int ret;
 	int tdls = 0;
 
@@ -2534,11 +2534,15 @@
 		if (!msg)
 			return -ENOBUFS;
 	} else {
+		u32 suite;
+
+		suite = wpa_alg_to_cipher_suite(alg, key_len);
+		if (!suite)
+			goto fail;
 		msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_NEW_KEY);
 		if (!msg ||
 		    nla_put(msg, NL80211_ATTR_KEY_DATA, key_len, key) ||
-		    nla_put_u32(msg, NL80211_ATTR_KEY_CIPHER,
-				wpa_alg_to_cipher_suite(alg, key_len)))
+		    nla_put_u32(msg, NL80211_ATTR_KEY_CIPHER, suite))
 			goto fail;
 		wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
 	}
@@ -2640,9 +2644,15 @@
 		      const u8 *key, size_t key_len)
 {
 	struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
+	u32 suite;
+
 	if (!key_attr)
 		return -1;
 
+	suite = wpa_alg_to_cipher_suite(alg, key_len);
+	if (!suite)
+		return -1;
+
 	if (defkey && alg == WPA_ALG_IGTK) {
 		if (nla_put_flag(msg, NL80211_KEY_DEFAULT_MGMT))
 			return -1;
@@ -2652,8 +2662,7 @@
 	}
 
 	if (nla_put_u8(msg, NL80211_KEY_IDX, key_idx) ||
-	    nla_put_u32(msg, NL80211_KEY_CIPHER,
-			wpa_alg_to_cipher_suite(alg, key_len)) ||
+	    nla_put_u32(msg, NL80211_KEY_CIPHER, suite) ||
 	    (seq && seq_len &&
 	     nla_put(msg, NL80211_KEY_SEQ, seq_len, seq)) ||
 	    nla_put(msg, NL80211_KEY_DATA, key_len, key))
@@ -5789,8 +5798,6 @@
 }
 
 
-#if defined(CONFIG_P2P) || defined(CONFIG_MESH)
-
 static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
 {
 	struct wpa_driver_nl80211_data *drv;
@@ -5826,8 +5833,6 @@
 	return 0;
 }
 
-#endif /* CONFIG_P2P || CONFIG_MESH */
-
 
 struct wdev_info {
 	u64 wdev_id;
@@ -5903,21 +5908,21 @@
 	}
 
 	if (!addr) {
-		if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
+		if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
 			os_memcpy(if_addr, bss->addr, ETH_ALEN);
 		else if (linux_get_ifhwaddr(drv->global->ioctl_sock,
-					    bss->ifname, if_addr) < 0) {
+					    ifname, if_addr) < 0) {
 			if (added)
 				nl80211_remove_iface(drv, ifidx);
 			return -1;
 		}
 	}
 
-#if defined(CONFIG_P2P) || defined(CONFIG_MESH)
 	if (!addr &&
 	    (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
-	     type == WPA_IF_P2P_GO || type == WPA_IF_MESH)) {
-		/* Enforce unique P2P Interface Address */
+	     type == WPA_IF_P2P_GO || type == WPA_IF_MESH ||
+	     type == WPA_IF_STATION)) {
+		/* Enforce unique address */
 		u8 new_addr[ETH_ALEN];
 
 		if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
@@ -5928,8 +5933,7 @@
 		}
 		if (nl80211_addr_in_use(drv->global, new_addr)) {
 			wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
-				   "for %s interface", type == WPA_IF_MESH ?
-				   "mesh" : "P2P group");
+				   "for interface %s type %d", ifname, type);
 			if (nl80211_vif_addr(drv, new_addr) < 0) {
 				if (added)
 					nl80211_remove_iface(drv, ifidx);
@@ -5944,7 +5948,6 @@
 		}
 		os_memcpy(if_addr, new_addr, ETH_ALEN);
 	}
-#endif /* CONFIG_P2P || CONFIG_MESH */
 
 	if (type == WPA_IF_AP_BSS) {
 		struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));