am 9ead16e2: Cumulative patch from commit d5fe4e6c18d94465e8fb4527d51df6e8539c4d6a

* commit '9ead16e203b81d44a2d84eadc2901ceeb7daf805':
  Cumulative patch from commit d5fe4e6c18d94465e8fb4527d51df6e8539c4d6a
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index e4681e9..2d09b67 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -1622,6 +1622,9 @@
 		if (ap_sta_bind_vlan(hapd, sta, old_vlanid) < 0)
 			break;
 
+		sta->session_timeout_set = !!session_timeout_set;
+		sta->session_timeout = session_timeout;
+
 		/* RFC 3580, Ch. 3.17 */
 		if (session_timeout_set && termination_action ==
 		    RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) {
@@ -2396,6 +2399,7 @@
 	size_t len;
 	/* TODO: get PMKLifetime from WPA parameters */
 	static const int dot11RSNAConfigPMKLifetime = 43200;
+	unsigned int session_timeout;
 
 #ifdef CONFIG_HS20
 	if (remediation && !sta->remediation) {
@@ -2430,9 +2434,13 @@
 #endif /* CONFIG_HS20 */
 
 	key = ieee802_1x_get_key(sta->eapol_sm, &len);
+	if (sta->session_timeout_set)
+		session_timeout = sta->session_timeout;
+	else
+		session_timeout = dot11RSNAConfigPMKLifetime;
 	if (success && key && len >= PMK_LEN && !sta->remediation &&
 	    !sta->hs20_deauth_requested &&
-	    wpa_auth_pmksa_add(sta->wpa_sm, key, dot11RSNAConfigPMKLifetime,
+	    wpa_auth_pmksa_add(sta->wpa_sm, key, session_timeout,
 			       sta->eapol_sm) == 0) {
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
 			       HOSTAPD_LEVEL_DEBUG,
diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c
index 4720b59..9de4cff 100644
--- a/src/ap/pmksa_cache_auth.c
+++ b/src/ap/pmksa_cache_auth.c
@@ -37,14 +37,12 @@
 
 static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
 {
-	if (entry == NULL)
-		return;
 	os_free(entry->identity);
 	wpabuf_free(entry->cui);
 #ifndef CONFIG_NO_RADIUS
 	radius_free_class(&entry->radius_class);
 #endif /* CONFIG_NO_RADIUS */
-	os_free(entry);
+	bin_clear_free(entry, sizeof(*entry));
 }
 
 
@@ -52,38 +50,42 @@
 			    struct rsn_pmksa_cache_entry *entry)
 {
 	struct rsn_pmksa_cache_entry *pos, *prev;
+	unsigned int hash;
 
 	pmksa->pmksa_count--;
 	pmksa->free_cb(entry, pmksa->ctx);
-	pos = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
+
+	/* unlink from hash list */
+	hash = PMKID_HASH(entry->pmkid);
+	pos = pmksa->pmkid[hash];
 	prev = NULL;
 	while (pos) {
 		if (pos == entry) {
-			if (prev != NULL) {
-				prev->hnext = pos->hnext;
-			} else {
-				pmksa->pmkid[PMKID_HASH(entry->pmkid)] =
-					pos->hnext;
-			}
+			if (prev != NULL)
+				prev->hnext = entry->hnext;
+			else
+				pmksa->pmkid[hash] = entry->hnext;
 			break;
 		}
 		prev = pos;
 		pos = pos->hnext;
 	}
 
+	/* unlink from entry list */
 	pos = pmksa->pmksa;
 	prev = NULL;
 	while (pos) {
 		if (pos == entry) {
 			if (prev != NULL)
-				prev->next = pos->next;
+				prev->next = entry->next;
 			else
-				pmksa->pmksa = pos->next;
+				pmksa->pmksa = entry->next;
 			break;
 		}
 		prev = pos;
 		pos = pos->next;
 	}
+
 	_pmksa_cache_free_entry(entry);
 }
 
@@ -188,6 +190,7 @@
 				   struct rsn_pmksa_cache_entry *entry)
 {
 	struct rsn_pmksa_cache_entry *pos, *prev;
+	int hash;
 
 	/* Add the new entry; order by expiration time */
 	pos = pmksa->pmksa;
@@ -205,8 +208,10 @@
 		entry->next = prev->next;
 		prev->next = entry;
 	}
-	entry->hnext = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
-	pmksa->pmkid[PMKID_HASH(entry->pmkid)] = entry;
+
+	hash = PMKID_HASH(entry->pmkid);
+	entry->hnext = pmksa->pmkid[hash];
+	pmksa->pmkid[hash] = entry;
 
 	pmksa->pmksa_count++;
 	if (prev == NULL)
@@ -342,6 +347,8 @@
 		_pmksa_cache_free_entry(prev);
 	}
 	eloop_cancel_timeout(pmksa_cache_expire, pmksa, NULL);
+	pmksa->pmksa_count = 0;
+	pmksa->pmksa = NULL;
 	for (i = 0; i < PMKID_HASH_SIZE; i++)
 		pmksa->pmkid[i] = NULL;
 	os_free(pmksa);
@@ -361,18 +368,22 @@
 {
 	struct rsn_pmksa_cache_entry *entry;
 
-	if (pmkid)
-		entry = pmksa->pmkid[PMKID_HASH(pmkid)];
-	else
-		entry = pmksa->pmksa;
-	while (entry) {
-		if ((spa == NULL ||
-		     os_memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
-		    (pmkid == NULL ||
-		     os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))
-			return entry;
-		entry = pmkid ? entry->hnext : entry->next;
+	if (pmkid) {
+		for (entry = pmksa->pmkid[PMKID_HASH(pmkid)]; entry;
+		     entry = entry->hnext) {
+			if ((spa == NULL ||
+			     os_memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
+			    os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0)
+				return entry;
+		}
+	} else {
+		for (entry = pmksa->pmksa; entry; entry = entry->next) {
+			if (spa == NULL ||
+			    os_memcmp(entry->spa, spa, ETH_ALEN) == 0)
+				return entry;
+		}
 	}
+
 	return NULL;
 }
 
@@ -394,15 +405,13 @@
 	struct rsn_pmksa_cache_entry *entry;
 	u8 new_pmkid[PMKID_LEN];
 
-	entry = pmksa->pmksa;
-	while (entry) {
+	for (entry = pmksa->pmksa; entry; entry = entry->next) {
 		if (os_memcmp(entry->spa, spa, ETH_ALEN) != 0)
 			continue;
 		rsn_pmkid(entry->pmk, entry->pmk_len, aa, spa, new_pmkid,
 			  wpa_key_mgmt_sha256(entry->akmp));
 		if (os_memcmp(new_pmkid, pmkid, PMKID_LEN) == 0)
 			return entry;
-		entry = entry->next;
 	}
 	return NULL;
 }
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 03db98f..faf32d8 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -60,6 +60,7 @@
 	unsigned int qos_map_enabled:1;
 	unsigned int remediation:1;
 	unsigned int hs20_deauth_requested:1;
+	unsigned int session_timeout_set:1;
 
 	u16 auth_alg;
 
@@ -135,6 +136,8 @@
 #ifdef CONFIG_SAE
 	struct sae_data *sae;
 #endif /* CONFIG_SAE */
+
+	u32 session_timeout; /* valid only if session_timeout_set == 1 */
 };
 
 
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 2bb8aab..1a16b5c 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1390,7 +1390,8 @@
 		if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
 		    sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
 		    version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
-			if (aes_wrap(sm->PTK.kek, (key_data_len - 8) / 8, buf,
+			if (aes_wrap(sm->PTK.kek, 16,
+				     (key_data_len - 8) / 8, buf,
 				     (u8 *) (key + 1))) {
 				os_free(hdr);
 				os_free(buf);
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 8a6ca71..781f15f 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -344,7 +344,8 @@
 	os_memcpy(f.s1kh_id, sm->addr, ETH_ALEN);
 	os_memset(f.pad, 0, sizeof(f.pad));
 
-	if (aes_wrap(r0kh->key, (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
+	if (aes_wrap(r0kh->key, sizeof(r0kh->key),
+		     (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
 		     f.nonce, frame.nonce) < 0)
 		return -1;
 
@@ -459,7 +460,7 @@
 	WPA_PUT_LE16(&subelem[2], gsm->GN & 0x03);
 	subelem[4] = gsm->GTK_len;
 	wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 5);
-	if (aes_wrap(sm->PTK.kek, key_len / 8, key, subelem + 13)) {
+	if (aes_wrap(sm->PTK.kek, 16, key_len / 8, key, subelem + 13)) {
 		os_free(subelem);
 		return NULL;
 	}
@@ -491,7 +492,7 @@
 	wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos);
 	pos += 6;
 	*pos++ = WPA_IGTK_LEN;
-	if (aes_wrap(sm->PTK.kek, WPA_IGTK_LEN / 8,
+	if (aes_wrap(sm->PTK.kek, 16, WPA_IGTK_LEN / 8,
 		     gsm->IGTK[gsm->GN_igtk - 4], pos)) {
 		os_free(subelem);
 		return NULL;
@@ -1336,7 +1337,8 @@
 	frame = (struct ft_r0kh_r1kh_pull_frame *) data;
 	/* aes_unwrap() does not support inplace decryption, so use a temporary
 	 * buffer for the data. */
-	if (aes_unwrap(r1kh->key, (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
+	if (aes_unwrap(r1kh->key, sizeof(r1kh->key),
+		       (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
 		       frame->nonce, f.nonce) < 0) {
 		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
 			   "request from " MACSTR, MAC2STR(src_addr));
@@ -1376,7 +1378,8 @@
 	r.pairwise = host_to_le16(pairwise);
 	os_memset(r.pad, 0, sizeof(r.pad));
 
-	if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
+	if (aes_wrap(r1kh->key, sizeof(r1kh->key),
+		     (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
 		     r.nonce, resp.nonce) < 0) {
 		os_memset(pmk_r0, 0, PMK_LEN);
 		return -1;
@@ -1464,7 +1467,8 @@
 	frame = (struct ft_r0kh_r1kh_resp_frame *) data;
 	/* aes_unwrap() does not support inplace decryption, so use a temporary
 	 * buffer for the data. */
-	if (aes_unwrap(r0kh->key, (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
+	if (aes_unwrap(r0kh->key, sizeof(r0kh->key),
+		       (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
 		       frame->nonce, f.nonce) < 0) {
 		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
 			   "response from " MACSTR, MAC2STR(src_addr));
@@ -1530,7 +1534,8 @@
 	frame = (struct ft_r0kh_r1kh_push_frame *) data;
 	/* aes_unwrap() does not support inplace decryption, so use a temporary
 	 * buffer for the data. */
-	if (aes_unwrap(r0kh->key, (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
+	if (aes_unwrap(r0kh->key, sizeof(r0kh->key),
+		       (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
 		       frame->timestamp, f.timestamp) < 0) {
 		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 push from "
 			   MACSTR, MAC2STR(src_addr));
@@ -1727,7 +1732,8 @@
 	WPA_PUT_LE32(f.timestamp, now.sec);
 	f.pairwise = host_to_le16(pairwise);
 	os_memset(f.pad, 0, sizeof(f.pad));
-	if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
+	if (aes_wrap(r1kh->key, sizeof(r1kh->key),
+		     (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
 		     f.timestamp, frame.timestamp) < 0)
 		return;
 
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index de0b222..ad3bdfd 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -60,7 +60,7 @@
 	QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY =  11,
 	QCA_NL80211_VENDOR_SUBCMD_NAN =  12,
 	QCA_NL80211_VENDOR_SUBMCD_STATS_EXT = 13,
-	/* 14..33 - reserved for QCA */
+	/* 14..49 - reserved for QCA */
 };
 
 
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index d91594e..4812f8d 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -345,9 +345,10 @@
  * @reply_len: Length of the reply buffer
  * Returns: 0 on success, -1 on failure
  *
- * This function will receive a pending control interface message. This
- * function will block if no messages are available. The received response will
- * be written to reply and reply_len is set to the actual length of the reply.
+ * This function will receive a pending control interface message. The received
+ * response will be written to reply and reply_len is set to the actual length
+ * of the reply.
+
  * wpa_ctrl_recv() is only used for event messages, i.e., wpa_ctrl_attach()
  * must have been used to register the control interface as an event monitor.
  */
diff --git a/src/crypto/aes-unwrap.c b/src/crypto/aes-unwrap.c
index 9dd5160..ec793d9 100644
--- a/src/crypto/aes-unwrap.c
+++ b/src/crypto/aes-unwrap.c
@@ -1,5 +1,5 @@
 /*
- * AES key unwrap (128-bit KEK, RFC3394)
+ * AES key unwrap (RFC3394)
  *
  * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
  *
@@ -14,26 +14,29 @@
 #include "aes_wrap.h"
 
 /**
- * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (RFC3394)
  * @kek: Key encryption key (KEK)
+ * @kek_len: Length of KEK in octets
  * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
  * bytes
  * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
  * @plain: Plaintext key, n * 64 bits
  * Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
  */
-int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain)
+int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
+	       u8 *plain)
 {
-	u8 a[8], *r, b[16];
+	u8 a[8], *r, b[AES_BLOCK_SIZE];
 	int i, j;
 	void *ctx;
+	unsigned int t;
 
 	/* 1) Initialize variables. */
 	os_memcpy(a, cipher, 8);
 	r = plain;
 	os_memcpy(r, cipher + 8, 8 * n);
 
-	ctx = aes_decrypt_init(kek, 16);
+	ctx = aes_decrypt_init(kek, kek_len);
 	if (ctx == NULL)
 		return -1;
 
@@ -48,7 +51,11 @@
 		r = plain + (n - 1) * 8;
 		for (i = n; i >= 1; i--) {
 			os_memcpy(b, a, 8);
-			b[7] ^= n * j + i;
+			t = n * j + i;
+			b[7] ^= t;
+			b[6] ^= t >> 8;
+			b[5] ^= t >> 16;
+			b[4] ^= t >> 24;
 
 			os_memcpy(b + 8, r, 8);
 			aes_decrypt(ctx, b, b);
diff --git a/src/crypto/aes-wrap.c b/src/crypto/aes-wrap.c
index 89d6f94..7ed34e8 100644
--- a/src/crypto/aes-wrap.c
+++ b/src/crypto/aes-wrap.c
@@ -1,5 +1,5 @@
 /*
- * AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * AES Key Wrap Algorithm (RFC3394)
  *
  * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
  *
@@ -14,19 +14,21 @@
 #include "aes_wrap.h"
 
 /**
- * aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
- * @kek: 16-octet Key encryption key (KEK)
+ * aes_wrap - Wrap keys with AES Key Wrap Algorithm (RFC3394)
+ * @kek: Key encryption key (KEK)
+ * @kek_len: Length of KEK in octets
  * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
  * bytes
  * @plain: Plaintext key to be wrapped, n * 64 bits
  * @cipher: Wrapped key, (n + 1) * 64 bits
  * Returns: 0 on success, -1 on failure
  */
-int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
+int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
 {
-	u8 *a, *r, b[16];
+	u8 *a, *r, b[AES_BLOCK_SIZE];
 	int i, j;
 	void *ctx;
+	unsigned int t;
 
 	a = cipher;
 	r = cipher + 8;
@@ -35,7 +37,7 @@
 	os_memset(a, 0xa6, 8);
 	os_memcpy(r, plain, 8 * n);
 
-	ctx = aes_encrypt_init(kek, 16);
+	ctx = aes_encrypt_init(kek, kek_len);
 	if (ctx == NULL)
 		return -1;
 
@@ -53,7 +55,11 @@
 			os_memcpy(b + 8, r, 8);
 			aes_encrypt(ctx, b, b);
 			os_memcpy(a, b, 8);
-			a[7] ^= n * j + i;
+			t = n * j + i;
+			a[7] ^= t;
+			a[6] ^= t >> 8;
+			a[5] ^= t >> 16;
+			a[4] ^= t >> 24;
 			os_memcpy(r, b + 8, 8);
 			r += 8;
 		}
diff --git a/src/crypto/aes_wrap.h b/src/crypto/aes_wrap.h
index 0433c04..6b3727c 100644
--- a/src/crypto/aes_wrap.h
+++ b/src/crypto/aes_wrap.h
@@ -1,7 +1,7 @@
 /*
  * AES-based functions
  *
- * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * - AES Key Wrap Algorithm (RFC3394)
  * - One-Key CBC MAC (OMAC1) hash with AES-128
  * - AES-128 CTR mode encryption
  * - AES-128 EAX mode encryption/decryption
@@ -18,8 +18,10 @@
 #ifndef AES_WRAP_H
 #define AES_WRAP_H
 
-int __must_check aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher);
-int __must_check aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain);
+int __must_check aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain,
+			  u8 *cipher);
+int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n,
+			    const u8 *cipher, u8 *plain);
 int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem,
 				      const u8 *addr[], const size_t *len,
 				      u8 *mac);
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 8876ebf..b4c59d1 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -40,7 +40,7 @@
 
 static BIGNUM * get_group5_prime(void)
 {
-#if OPENSSL_VERSION_NUMBER < 0x00908000
+#if OPENSSL_VERSION_NUMBER < 0x00908000 || defined(OPENSSL_IS_BORINGSSL)
 	static const unsigned char RFC3526_PRIME_1536[] = {
 		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
 		0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
@@ -130,7 +130,7 @@
 	}
 	pkey[i] = next | 1;
 
-	DES_set_key(&pkey, &ks);
+	DES_set_key((DES_cblock *) &pkey, &ks);
 	DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
 			DES_ENCRYPT);
 }
@@ -199,8 +199,10 @@
 	switch (keylen) {
 	case 16:
 		return EVP_aes_128_ecb();
+#ifndef OPENSSL_IS_BORINGSSL
 	case 24:
 		return EVP_aes_192_ecb();
+#endif /* OPENSSL_IS_BORINGSSL */
 	case 32:
 		return EVP_aes_256_ecb();
 	}
@@ -378,9 +380,11 @@
 		case 16:
 			cipher = EVP_aes_128_cbc();
 			break;
+#ifndef OPENSSL_IS_BORINGSSL
 		case 24:
 			cipher = EVP_aes_192_cbc();
 			break;
+#endif /* OPENSSL_IS_BORINGSSL */
 		case 32:
 			cipher = EVP_aes_256_cbc();
 			break;
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index d2d6600..e153422 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -38,14 +38,26 @@
 #define OPENSSL_SUPPORTS_CTX_APP_DATA
 #endif
 
-#ifdef SSL_F_SSL_SET_SESSION_TICKET_EXT
-#ifdef SSL_OP_NO_TICKET
+#if OPENSSL_VERSION_NUMBER < 0x10000000L
+/* ERR_remove_thread_state replaces ERR_remove_state and the latter is
+ * deprecated. However, OpenSSL 0.9.8 doesn't include
+ * ERR_remove_thread_state. */
+#define ERR_remove_thread_state(tid) ERR_remove_state(0)
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
 /*
  * Session ticket override patch was merged into OpenSSL 0.9.9 tree on
  * 2008-11-15. This version uses a bit different API compared to the old patch.
  */
 #define CONFIG_OPENSSL_TICKET_OVERRIDE
 #endif
+
+#if defined(OPENSSL_IS_BORINGSSL)
+/* stack_index_t is the return type of OpenSSL's sk_XXX_num() functions. */
+typedef size_t stack_index_t;
+#else
+typedef int stack_index_t;
 #endif
 
 #ifdef SSL_set_tlsext_status_type
@@ -853,7 +865,7 @@
 		ENGINE_cleanup();
 #endif /* OPENSSL_NO_ENGINE */
 		CRYPTO_cleanup_all_ex_data();
-		ERR_remove_state(0);
+		ERR_remove_thread_state(NULL);
 		ERR_free_strings();
 		EVP_cleanup();
 		os_free(tls_global->ocsp_stapling_response);
@@ -1102,7 +1114,8 @@
 {
 	GENERAL_NAME *gen;
 	void *ext;
-	int i, found = 0;
+	int found = 0;
+	stack_index_t i;
 
 	ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
 
@@ -1204,6 +1217,7 @@
 	GENERAL_NAME *gen;
 	void *ext;
 	int i;
+	stack_index_t j;
 	int dns_name = 0;
 	X509_NAME *name;
 
@@ -1211,8 +1225,8 @@
 
 	ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
 
-	for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
-		gen = sk_GENERAL_NAME_value(ext, i);
+	for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) {
+		gen = sk_GENERAL_NAME_value(ext, j);
 		if (gen->type != GEN_DNS)
 			continue;
 		dns_name++;
@@ -1639,7 +1653,7 @@
 	if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
 		BIO *bio = BIO_from_keystore(&ca_cert[11]);
 		STACK_OF(X509_INFO) *stack = NULL;
-		int i;
+		stack_index_t i;
 
 		if (bio) {
 			stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
@@ -3386,9 +3400,15 @@
  * commented out unless explicitly needed for EAP-FAST in order to be able to
  * build this file with unmodified openssl. */
 
+#ifdef OPENSSL_IS_BORINGSSL
+static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
+			   STACK_OF(SSL_CIPHER) *peer_ciphers,
+			   const SSL_CIPHER **cipher, void *arg)
+#else /* OPENSSL_IS_BORINGSSL */
 static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
 			   STACK_OF(SSL_CIPHER) *peer_ciphers,
 			   SSL_CIPHER **cipher, void *arg)
+#endif /* OPENSSL_IS_BORINGSSL */
 {
 	struct tls_connection *conn = arg;
 	int ret;
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 501314b..6af7294 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -411,6 +411,25 @@
 			  */
 };
 
+struct hostapd_freq_params {
+	int mode;
+	int freq;
+	int channel;
+	/* for HT */
+	int ht_enabled;
+	int sec_channel_offset; /* 0 = HT40 disabled, -1 = HT40 enabled,
+				 * secondary channel below primary, 1 = HT40
+				 * enabled, secondary channel above primary */
+
+	/* for VHT */
+	int vht_enabled;
+
+	/* valid for both HT and VHT, center_freq2 is non-zero
+	 * only for bandwidth 80 and an 80+80 channel */
+	int center_freq1, center_freq2;
+	int bandwidth;
+};
+
 /**
  * struct wpa_driver_associate_params - Association parameters
  * Data for struct wpa_driver_ops::associate().
@@ -443,11 +462,9 @@
 	size_t ssid_len;
 
 	/**
-	 * freq - Frequency of the channel the selected AP is using
-	 * Frequency that the selected AP is using (in MHz as
-	 * reported in the scan results)
+	 * freq - channel parameters
 	 */
-	int freq;
+	struct hostapd_freq_params freq;
 
 	/**
 	 * freq_hint - Frequency of the channel the proposed AP is using
@@ -1091,25 +1108,6 @@
 	size_t supp_oper_classes_len;
 };
 
-struct hostapd_freq_params {
-	int mode;
-	int freq;
-	int channel;
-	/* for HT */
-	int ht_enabled;
-	int sec_channel_offset; /* 0 = HT40 disabled, -1 = HT40 enabled,
-				 * secondary channel below primary, 1 = HT40
-				 * enabled, secondary channel above primary */
-
-	/* for VHT */
-	int vht_enabled;
-
-	/* valid for both HT and VHT, center_freq2 is non-zero
-	 * only for bandwidth 80 and an 80+80 channel */
-	int center_freq1, center_freq2;
-	int bandwidth;
-};
-
 struct mac_address {
 	u8 addr[ETH_ALEN];
 };
@@ -2503,6 +2501,7 @@
 	 * @dialog_token: Dialog Token to use in the message (if needed)
 	 * @status_code: Status Code or Reason Code to use (if needed)
 	 * @peer_capab: TDLS peer capability (TDLS_PEER_* bitfield)
+	 * @initiator: Is the current end the TDLS link initiator
 	 * @buf: TDLS IEs to add to the message
 	 * @len: Length of buf in octets
 	 * Returns: 0 on success, negative (<0) on failure
@@ -2512,7 +2511,7 @@
 	 */
 	int (*send_tdls_mgmt)(void *priv, const u8 *dst, u8 action_code,
 			      u8 dialog_token, u16 status_code, u32 peer_capab,
-			      const u8 *buf, size_t len);
+			      int initiator, const u8 *buf, size_t len);
 
 	/**
 	 * tdls_oper - Ask the driver to perform high-level TDLS operations
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 5c922a0..d030474 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -331,7 +331,7 @@
 
 	int eapol_sock; /* socket for EAPOL frames */
 
-	struct nl_sock *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
+	struct nl_handle *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
 
 	int default_if_indices[16];
 	int *if_indices;
@@ -358,7 +358,8 @@
 					    void *timeout_ctx);
 static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
 				       enum nl80211_iftype nlmode);
-static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss, int freq);
+static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
+					    struct hostapd_freq_params *freq);
 
 static int
 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
@@ -588,6 +589,20 @@
 }
 
 
+static struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv,
+					 int ifindex)
+{
+	struct i802_bss *bss;
+
+	for (bss = drv->first_bss; bss; bss = bss->next) {
+		if (bss->ifindex == ifindex)
+			return bss;
+	}
+
+	return NULL;
+}
+
+
 static void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
 {
 	if (drv->associated)
@@ -1306,6 +1321,28 @@
 				   "event since interface %s is marked "
 				   "removed", drv->first_bss->ifname);
 		} else {
+			struct i802_bss *bss;
+			u8 addr[ETH_ALEN];
+
+			/* Re-read MAC address as it may have changed */
+			bss = get_bss_ifindex(drv, ifi->ifi_index);
+			if (bss &&
+			    linux_get_ifhwaddr(drv->global->ioctl_sock,
+					       bss->ifname, addr) < 0) {
+				wpa_printf(MSG_DEBUG,
+					   "nl80211: %s: failed to re-read MAC address",
+					   bss->ifname);
+			} else if (bss &&
+				   os_memcmp(addr, bss->addr, ETH_ALEN) != 0) {
+				wpa_printf(MSG_DEBUG,
+					   "nl80211: Own MAC address on ifindex %d (%s) changed from "
+					   MACSTR " to " MACSTR,
+					   ifi->ifi_index, bss->ifname,
+					   MAC2STR(bss->addr),
+					   MAC2STR(addr));
+				os_memcpy(bss->addr, addr, ETH_ALEN);
+			}
+
 			wpa_printf(MSG_DEBUG, "nl80211: Interface up");
 			drv->if_disabled = 0;
 			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
@@ -1688,10 +1725,7 @@
 		return;
 
 	ifidx = nla_get_u32(ifindex);
-	for (bss = drv->first_bss; bss; bss = bss->next)
-		if (bss->ifindex == ifidx)
-			break;
-
+	bss = get_bss_ifindex(drv, ifidx);
 	if (bss == NULL) {
 		wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
 			   ifidx);
@@ -4938,7 +4972,7 @@
 				   "interface %s from bridge %s: %s",
 				   bss->ifname, bss->brname, strerror(errno));
 		if (drv->rtnl_sk)
-			nl_socket_free(drv->rtnl_sk);
+			nl80211_handle_destroy(drv->rtnl_sk);
 	}
 	if (bss->added_bridge) {
 		if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
@@ -8648,9 +8682,6 @@
 				 struct wpa_driver_associate_params *params)
 {
 	enum nl80211_iftype nlmode, old_mode;
-	struct hostapd_freq_params freq = {
-		.freq = params->freq,
-	};
 
 	if (params->p2p) {
 		wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
@@ -8665,7 +8696,7 @@
 		return -1;
 	}
 
-	if (nl80211_set_channel(drv->first_bss, &freq, 0)) {
+	if (nl80211_set_channel(drv->first_bss, &params->freq, 0)) {
 		if (old_mode != nlmode)
 			wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
 		nl80211_remove_monitor_interface(drv);
@@ -8719,7 +8750,7 @@
 
 	wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
 
-	if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, params->freq)) {
+	if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, &params->freq)) {
 		wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
 			   "IBSS mode");
 		return -1;
@@ -8743,8 +8774,16 @@
 	os_memcpy(drv->ssid, params->ssid, params->ssid_len);
 	drv->ssid_len = params->ssid_len;
 
-	wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
-	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
+	wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq.freq);
+	wpa_printf(MSG_DEBUG, "  * ht_enabled=%d", params->freq.ht_enabled);
+	wpa_printf(MSG_DEBUG, "  * sec_channel_offset=%d",
+		   params->freq.sec_channel_offset);
+	wpa_printf(MSG_DEBUG, "  * vht_enabled=%d", params->freq.vht_enabled);
+	wpa_printf(MSG_DEBUG, "  * center_freq1=%d", params->freq.center_freq1);
+	wpa_printf(MSG_DEBUG, "  * center_freq2=%d", params->freq.center_freq2);
+	wpa_printf(MSG_DEBUG, "  * bandwidth=%d", params->freq.bandwidth);
+	if (nl80211_put_freq_params(msg, &params->freq) < 0)
+		goto nla_put_failure;
 
 	if (params->beacon_int > 0) {
 		wpa_printf(MSG_DEBUG, "  * beacon_int=%d", params->beacon_int);
@@ -8822,10 +8861,10 @@
 			params->bssid_hint);
 	}
 
-	if (params->freq) {
-		wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
-		NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
-		drv->assoc_freq = params->freq;
+	if (params->freq.freq) {
+		wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq.freq);
+		NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq.freq);
+		drv->assoc_freq = params->freq.freq;
 	} else
 		drv->assoc_freq = 0;
 
@@ -9316,13 +9355,11 @@
 }
 
 
-static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss, int freq)
+static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
+					    struct hostapd_freq_params *freq)
 {
-	struct hostapd_freq_params freq_params;
-	os_memset(&freq_params, 0, sizeof(freq_params));
-	freq_params.freq = freq;
 	return wpa_driver_nl80211_set_mode_impl(bss, NL80211_IFTYPE_ADHOC,
-						&freq_params);
+						freq);
 }
 
 
@@ -11605,7 +11642,8 @@
 
 static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
 				  u8 dialog_token, u16 status_code,
-				  u32 peer_capab, const u8 *buf, size_t len)
+				  u32 peer_capab, int initiator, const u8 *buf,
+				  size_t len)
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -11636,6 +11674,8 @@
 		 */
 		NLA_PUT_U32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY, peer_capab);
 	}
+	if (initiator)
+		NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_INITIATOR);
 	NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
 
 	return send_and_recv_msgs(drv, msg, NULL, NULL);
diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c
index 3608b52..66edfa7 100644
--- a/src/drivers/driver_test.c
+++ b/src/drivers/driver_test.c
@@ -1478,7 +1478,7 @@
 	struct wpa_driver_test_data *drv = dbss->drv;
 	wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
 		   "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
-		   __func__, priv, params->freq, params->pairwise_suite,
+		   __func__, priv, params->freq.freq, params->pairwise_suite,
 		   params->group_suite, params->key_mgmt_suite,
 		   params->auth_alg, params->mode);
 	wpa_driver_update_mode(drv, params->mode == IEEE80211_MODE_AP);
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index 459ac48..1b3a757 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -2119,7 +2119,8 @@
 	if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0)
 		ret = -1;
 #endif /* CONFIG_IEEE80211W */
-	if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0)
+	if (params->freq.freq &&
+	    wpa_driver_wext_set_freq(drv, params->freq.freq) < 0)
 		ret = -1;
 	if (!drv->cfg80211 &&
 	    wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
index 406010d..4b28dc0 100644
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -503,6 +503,9 @@
  *	TX status event pertaining to the TX request.
  *	%NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
  *	management frames at CCK rate or not in 2GHz band.
+ *	%NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA
+ *	counters which will be updated to the current value. This attribute
+ *	is used during CSA period.
  * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
  *	command may be used with the corresponding cookie to cancel the wait
  *	time if it is known that it is no longer necessary.
@@ -719,6 +722,22 @@
  *	QoS mapping is relevant for IP packets, it is only valid during an
  *	association. This is cleared on disassociation and AP restart.
  *
+ * @NL80211_CMD_ADD_TX_TS: Ask the kernel to add a traffic stream for the given
+ *	%NL80211_ATTR_TSID and %NL80211_ATTR_MAC with %NL80211_ATTR_USER_PRIO
+ *	and %NL80211_ATTR_ADMITTED_TIME parameters.
+ *	Note that the action frame handshake with the AP shall be handled by
+ *	userspace via the normal management RX/TX framework, this only sets
+ *	up the TX TS in the driver/device.
+ *	If the admitted time attribute is not added then the request just checks
+ *	if a subsequent setup could be successful, the intent is to use this to
+ *	avoid setting up a session with the AP when local restrictions would
+ *	make that impossible. However, the subsequent "real" setup may still
+ *	fail even if the check was successful.
+ * @NL80211_CMD_DEL_TX_TS: Remove an existing TS with the %NL80211_ATTR_TSID
+ *	and %NL80211_ATTR_MAC parameters. It isn't necessary to call this
+ *	before removing a station entry entirely, or before disassociating
+ *	or similar, cleanup will happen in the driver/device in this case.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -890,6 +909,9 @@
 
 	NL80211_CMD_SET_QOS_MAP,
 
+	NL80211_CMD_ADD_TX_TS,
+	NL80211_CMD_DEL_TX_TS,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1525,10 +1547,10 @@
  *	operation).
  * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
  *	for the time while performing a channel switch.
- * @NL80211_ATTR_CSA_C_OFF_BEACON: Offset of the channel switch counter
- *	field in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
- * @NL80211_ATTR_CSA_C_OFF_PRESP: Offset of the channel switch counter
- *	field in the probe response (%NL80211_ATTR_PROBE_RESP).
+ * @NL80211_ATTR_CSA_C_OFF_BEACON: An array of offsets (u16) to the channel
+ *	switch counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
+ * @NL80211_ATTR_CSA_C_OFF_PRESP: An array of offsets (u16) to the channel
+ *	switch counters in the probe response (%NL80211_ATTR_PROBE_RESP).
  *
  * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
  *	As specified in the &enum nl80211_rxmgmt_flags.
@@ -1576,6 +1598,11 @@
  *	advertise values that cannot always be met. In such cases, an attempt
  *	to add a new station entry with @NL80211_CMD_NEW_STATION may fail.
  *
+ * @NL80211_ATTR_CSA_C_OFFSETS_TX: An array of csa counter offsets (u16) which
+ *	should be updated when the frame is transmitted.
+ * @NL80211_ATTR_MAX_CSA_COUNTERS: U8 attribute used to advertise the maximum
+ *	supported number of csa counters.
+ *
  * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32.
  *	As specified in the &enum nl80211_tdls_peer_capability.
  *
@@ -1583,6 +1610,34 @@
  *	creation then the new interface will be owned by the netlink socket
  *	that created it and will be destroyed when the socket is closed
  *
+ * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is
+ *	the TDLS link initiator.
+ *
+ * @NL80211_ATTR_USE_RRM: flag for indicating whether the current connection
+ *	shall support Radio Resource Measurements (11k). This attribute can be
+ *	used with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests.
+ *	User space applications are expected to use this flag only if the
+ *	underlying device supports these minimal RRM features:
+ *		%NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES,
+ *		%NL80211_FEATURE_QUIET,
+ *	If this flag is used, driver must add the Power Capabilities IE to the
+ *	association request. In addition, it must also set the RRM capability
+ *	flag in the association request's Capability Info field.
+ *
+ * @NL80211_ATTR_WIPHY_DYN_ACK: flag attribute used to enable ACK timeout
+ *	estimation algorithm (dynack). In order to activate dynack
+ *	%NL80211_FEATURE_ACKTO_ESTIMATION feature flag must be set by lower
+ *	drivers to indicate dynack capability. Dynack is automatically disabled
+ *	setting valid value for coverage class.
+ *
+ * @NL80211_ATTR_TSID: a TSID value (u8 attribute)
+ * @NL80211_ATTR_USER_PRIO: user priority value (u8 attribute)
+ * @NL80211_ATTR_ADMITTED_TIME: admitted time in units of 32 microseconds
+ *	(per second) (u16 attribute)
+ *
+ * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
+ *	&enum nl80211_smps_mode.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1920,6 +1975,21 @@
 
 	NL80211_ATTR_IFACE_SOCKET_OWNER,
 
+	NL80211_ATTR_CSA_C_OFFSETS_TX,
+	NL80211_ATTR_MAX_CSA_COUNTERS,
+
+	NL80211_ATTR_TDLS_INITIATOR,
+
+	NL80211_ATTR_USE_RRM,
+
+	NL80211_ATTR_WIPHY_DYN_ACK,
+
+	NL80211_ATTR_TSID,
+	NL80211_ATTR_USER_PRIO,
+	NL80211_ATTR_ADMITTED_TIME,
+
+	NL80211_ATTR_SMPS_MODE,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -2188,6 +2258,8 @@
  *	Contains a nested array of signal strength attributes (u8, dBm)
  * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
  *	Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
+ * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the
+ *	802.11 header (u32, kbps)
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
@@ -2219,6 +2291,7 @@
 	NL80211_STA_INFO_TX_BYTES64,
 	NL80211_STA_INFO_CHAIN_SIGNAL,
 	NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
+	NL80211_STA_INFO_EXPECTED_THROUGHPUT,
 
 	/* keep last */
 	__NL80211_STA_INFO_AFTER_LAST,
@@ -3036,14 +3109,20 @@
  * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets)
  * @NL80211_BSS_FREQUENCY: frequency in MHz (u32)
  * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64)
+ *	(if @NL80211_BSS_PRESP_DATA is present then this is known to be
+ *	from a probe response, otherwise it may be from the same beacon
+ *	that the NL80211_BSS_BEACON_TSF will be from)
  * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
  * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16)
  * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the
  *	raw information elements from the probe response/beacon (bin);
- *	if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are
- *	from a Probe Response frame; otherwise they are from a Beacon frame.
+ *	if the %NL80211_BSS_BEACON_IES attribute is present and the data is
+ *	different then the IEs here are from a Probe Response frame; otherwise
+ *	they are from a Beacon frame.
  *	However, if the driver does not indicate the source of the IEs, these
  *	IEs may be from either frame subtype.
+ *	If present, the @NL80211_BSS_PRESP_DATA attribute indicates that the
+ *	data here is known to be from a probe response, without any heuristics.
  * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon
  *	in mBm (100 * dBm) (s32)
  * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
@@ -3055,6 +3134,10 @@
  *	yet been received
  * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel
  *	(u32, enum nl80211_bss_scan_width)
+ * @NL80211_BSS_BEACON_TSF: TSF of the last received beacon (u64)
+ *	(not present if no beacon frame has been received yet)
+ * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and
+ *	@NL80211_BSS_TSF is known to be from a probe response (flag attribute)
  * @__NL80211_BSS_AFTER_LAST: internal
  * @NL80211_BSS_MAX: highest BSS attribute
  */
@@ -3072,6 +3155,8 @@
 	NL80211_BSS_SEEN_MS_AGO,
 	NL80211_BSS_BEACON_IES,
 	NL80211_BSS_CHAN_WIDTH,
+	NL80211_BSS_BEACON_TSF,
+	NL80211_BSS_PRESP_DATA,
 
 	/* keep last */
 	__NL80211_BSS_AFTER_LAST,
@@ -3688,6 +3773,8 @@
  *	different channels may be used within this group.
  * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap
  *	of supported channel widths for radar detection.
+ * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
+ *	of supported regulatory regions for radar detection.
  * @NUM_NL80211_IFACE_COMB: number of attributes
  * @MAX_NL80211_IFACE_COMB: highest attribute number
  *
@@ -3721,6 +3808,7 @@
 	NL80211_IFACE_COMB_STA_AP_BI_MATCH,
 	NL80211_IFACE_COMB_NUM_CHANNELS,
 	NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
+	NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
 
 	/* keep last */
 	NUM_NL80211_IFACE_COMB,
@@ -3894,6 +3982,8 @@
  * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
  *	to work properly to suppport receiving regulatory hints from
  *	cellular base stations.
+ * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: (no longer available, only
+ *	here to reserve the value for API/ABI compatibility)
  * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of
  *	equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station
  *	mode
@@ -3932,13 +4022,33 @@
  * @NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE: This driver supports dynamic
  *	channel bandwidth change (e.g., HT 20 <-> 40 MHz channel) during the
  *	lifetime of a BSS.
+ * @NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES: This device adds a DS Parameter
+ *	Set IE to probe requests.
+ * @NL80211_FEATURE_WFA_TPC_IE_IN_PROBES: This device adds a WFA TPC Report IE
+ *	to probe requests.
+ * @NL80211_FEATURE_QUIET: This device, in client mode, supports Quiet Period
+ *	requests sent to it by an AP.
+ * @NL80211_FEATURE_TX_POWER_INSERTION: This device is capable of inserting the
+ *	current tx power value into the TPC Report IE in the spectrum
+ *	management TPC Report action frame, and in the Radio Measurement Link
+ *	Measurement Report action frame.
+ * @NL80211_FEATURE_ACKTO_ESTIMATION: This driver supports dynamic ACK timeout
+ *	estimation (dynack). %NL80211_ATTR_WIPHY_DYN_ACK flag attribute is used
+ *	to enable dynack.
+ * @NL80211_FEATURE_STATIC_SMPS: Device supports static spatial
+ *	multiplexing powersave, ie. can turn off all but one chain
+ *	even on HT connections that should be using more chains.
+ * @NL80211_FEATURE_DYNAMIC_SMPS: Device supports dynamic spatial
+ *	multiplexing powersave, ie. can turn off all but one chain
+ *	and then wake the rest up as required after, for example,
+ *	rts/cts handshake.
  */
 enum nl80211_feature_flags {
 	NL80211_FEATURE_SK_TX_STATUS			= 1 << 0,
 	NL80211_FEATURE_HT_IBSS				= 1 << 1,
 	NL80211_FEATURE_INACTIVITY_TIMER		= 1 << 2,
 	NL80211_FEATURE_CELL_BASE_REG_HINTS		= 1 << 3,
-	/* bit 4 is reserved - don't use */
+	NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL	= 1 << 4,
 	NL80211_FEATURE_SAE				= 1 << 5,
 	NL80211_FEATURE_LOW_PRIORITY_SCAN		= 1 << 6,
 	NL80211_FEATURE_SCAN_FLUSH			= 1 << 7,
@@ -3953,6 +4063,13 @@
 	NL80211_FEATURE_USERSPACE_MPM			= 1 << 16,
 	NL80211_FEATURE_ACTIVE_MONITOR			= 1 << 17,
 	NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE	= 1 << 18,
+	NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES	= 1 << 19,
+	NL80211_FEATURE_WFA_TPC_IE_IN_PROBES		= 1 << 20,
+	NL80211_FEATURE_QUIET				= 1 << 21,
+	NL80211_FEATURE_TX_POWER_INSERTION		= 1 << 22,
+	NL80211_FEATURE_ACKTO_ESTIMATION		= 1 << 23,
+	NL80211_FEATURE_STATIC_SMPS			= 1 << 24,
+	NL80211_FEATURE_DYNAMIC_SMPS			= 1 << 25,
 };
 
 /**
@@ -4027,6 +4144,25 @@
 };
 
 /**
+ * enum nl80211_smps_mode - SMPS mode
+ *
+ * Requested SMPS mode (for AP mode)
+ *
+ * @NL80211_SMPS_OFF: SMPS off (use all antennas).
+ * @NL80211_SMPS_STATIC: static SMPS (use a single antenna)
+ * @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and
+ *	turn on other antennas after CTS/RTS).
+ */
+enum nl80211_smps_mode {
+	NL80211_SMPS_OFF,
+	NL80211_SMPS_STATIC,
+	NL80211_SMPS_DYNAMIC,
+
+	__NL80211_SMPS_AFTER_LAST,
+	NL80211_SMPS_MAX = __NL80211_SMPS_AFTER_LAST - 1
+};
+
+/**
  * enum nl80211_radar_event - type of radar event for DFS operation
  *
  * Type of event to be used with NL80211_ATTR_RADAR_EVENT to inform userspace
diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c
index fdcff7f..631c363 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -106,9 +106,11 @@
         case 21:
 		nid = NID_secp521r1;
 		break;
+#ifndef OPENSSL_IS_BORINGSSL
         case 25:
 		nid = NID_X9_62_prime192v1;
 		break;
+#endif /* OPENSSL_IS_BORINGSSL */
         case 26:
 		nid = NID_secp224r1;
 		break;
diff --git a/src/eap_server/eap_server_fast.c b/src/eap_server/eap_server_fast.c
index 4691e72..2692bce 100644
--- a/src/eap_server/eap_server_fast.c
+++ b/src/eap_server/eap_server_fast.c
@@ -161,8 +161,8 @@
 		return 0;
 	}
 
-	if (aes_unwrap(data->pac_opaque_encr, (pac_opaque_len - 8) / 8,
-		       pac_opaque, buf) < 0) {
+	if (aes_unwrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr),
+		       (pac_opaque_len - 8) / 8, pac_opaque, buf) < 0) {
 		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to decrypt "
 			   "PAC-Opaque");
 		os_free(buf);
@@ -731,8 +731,8 @@
 		os_free(pac_buf);
 		return NULL;
 	}
-	if (aes_wrap(data->pac_opaque_encr, pac_len / 8, pac_buf,
-		     pac_opaque) < 0) {
+	if (aes_wrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr),
+		     pac_len / 8, pac_buf, pac_opaque) < 0) {
 		os_free(pac_buf);
 		os_free(pac_opaque);
 		return NULL;
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 56c195a..b1cf32d 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1451,7 +1451,7 @@
 		os_memcpy(body->sak, cipher_suite_tbl[cs_index].id, CS_ID_LEN);
 		sak_pos = CS_ID_LEN;
 	}
-	if (aes_wrap(participant->kek.key,
+	if (aes_wrap(participant->kek.key, 16,
 		     cipher_suite_tbl[cs_index].sak_len / 8,
 		     sak->key, body->sak + sak_pos)) {
 		wpa_printf(MSG_ERROR, "KaY: AES wrap failed");
@@ -1611,7 +1611,7 @@
 		wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
 		return -1;
 	}
-	if (aes_unwrap(participant->kek.key, sak_len >> 3, wrap_sak,
+	if (aes_unwrap(participant->kek.key, 16, sak_len >> 3, wrap_sak,
 		       unwrap_sak)) {
 		wpa_printf(MSG_ERROR, "KaY: AES unwrap failed");
 		os_free(unwrap_sak);
diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c
index b5a87fc..885291a 100644
--- a/src/rsn_supp/pmksa_cache.c
+++ b/src/rsn_supp/pmksa_cache.c
@@ -35,7 +35,7 @@
 
 static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
 {
-	os_free(entry);
+	bin_clear_free(entry, sizeof(*entry));
 }
 
 
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 93ae143..8cb19a2 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -218,26 +218,29 @@
 static int wpa_tdls_send_tpk_msg(struct wpa_sm *sm, const u8 *dst,
 				 u8 action_code, u8 dialog_token,
 				 u16 status_code, u32 peer_capab,
-				 const u8 *buf, size_t len)
+				 int initiator, const u8 *buf, size_t len)
 {
 	return wpa_sm_send_tdls_mgmt(sm, dst, action_code, dialog_token,
-				     status_code, peer_capab, buf, len);
+				     status_code, peer_capab, initiator, buf,
+				     len);
 }
 
 
 static int wpa_tdls_tpk_send(struct wpa_sm *sm, const u8 *dest, u8 action_code,
 			     u8 dialog_token, u16 status_code, u32 peer_capab,
-			     const u8 *msg, size_t msg_len)
+			     int initiator, const u8 *msg, size_t msg_len)
 {
 	struct wpa_tdls_peer *peer;
 
 	wpa_printf(MSG_DEBUG, "TDLS: TPK send dest=" MACSTR " action_code=%u "
-		   "dialog_token=%u status_code=%u peer_capab=%u msg_len=%u",
+		   "dialog_token=%u status_code=%u peer_capab=%u initiator=%d "
+		   "msg_len=%u",
 		   MAC2STR(dest), action_code, dialog_token, status_code,
-		   peer_capab, (unsigned int) msg_len);
+		   peer_capab, initiator, (unsigned int) msg_len);
 
 	if (wpa_tdls_send_tpk_msg(sm, dest, action_code, dialog_token,
-				  status_code, peer_capab, msg, msg_len)) {
+				  status_code, peer_capab, initiator, msg,
+				  msg_len)) {
 		wpa_printf(MSG_INFO, "TDLS: Failed to send message "
 			   "(action_code=%u)", action_code);
 		return -1;
@@ -333,6 +336,7 @@
 					  peer->sm_tmr.dialog_token,
 					  peer->sm_tmr.status_code,
 					  peer->sm_tmr.peer_capab,
+					  peer->initiator,
 					  peer->sm_tmr.buf,
 					  peer->sm_tmr.buf_len)) {
 			wpa_printf(MSG_INFO, "TDLS: Failed to retry "
@@ -793,7 +797,7 @@
 
 	/* request driver to send Teardown using this FTIE */
 	wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0,
-			  reason_code, 0, rbuf, pos - rbuf);
+			  reason_code, 0, peer->initiator, rbuf, pos - rbuf);
 	os_free(rbuf);
 
 	return 0;
@@ -968,17 +972,19 @@
  *	appropriate status code mentioning reason for error/failure.
  * @dst 	- MAC addr of Peer station
  * @tdls_action - TDLS frame type for which error code is sent
+ * @initiator   - was this end the initiator of the connection
  * @status 	- status code mentioning reason
  */
 
 static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
-			       u8 tdls_action, u8 dialog_token, u16 status)
+			       u8 tdls_action, u8 dialog_token, int initiator,
+			       u16 status)
 {
 	wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
 		   " (action=%u status=%u)",
 		   MAC2STR(dst), tdls_action, status);
 	return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
-				 0, NULL, 0);
+				 0, initiator, NULL, 0);
 }
 
 
@@ -1184,7 +1190,7 @@
 		   MAC2STR(peer->addr));
 
 	status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST,
-				   1, 0, 0, rbuf, pos - rbuf);
+				   1, 0, 0, peer->initiator, rbuf, pos - rbuf);
 	os_free(rbuf);
 
 	return status;
@@ -1274,7 +1280,8 @@
 
 skip_ies:
 	status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE,
-				   dtoken, 0, 0, rbuf, pos - rbuf);
+				   dtoken, 0, 0, peer->initiator, rbuf,
+				   pos - rbuf);
 	os_free(rbuf);
 
 	return status;
@@ -1371,7 +1378,8 @@
 		peer_capab |= TDLS_PEER_WMM;
 
 	status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM,
-				   dtoken, 0, peer_capab, rbuf, pos - rbuf);
+				   dtoken, 0, peer_capab, peer->initiator,
+				   rbuf, pos - rbuf);
 	os_free(rbuf);
 
 	return status;
@@ -1457,7 +1465,7 @@
 	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
 skip_ies:
 	status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
-				   dialog_token, 0, 0,  rbuf, pos - rbuf);
+				   dialog_token, 0, 0, 0, rbuf, pos - rbuf);
 	os_free(rbuf);
 
 	return status;
@@ -1528,7 +1536,7 @@
 	wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
 		   MACSTR, MAC2STR(addr));
 	return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
-				 1, 0, 0, NULL, 0);
+				 1, 0, 0, 1, NULL, 0);
 }
 
 
@@ -1713,8 +1721,8 @@
 				       peer->supp_rates, peer->supp_rates_len,
 				       peer->ht_capabilities,
 				       peer->vht_capabilities,
-				       peer->qos_info, peer->ext_capab,
-				       peer->ext_capab_len,
+				       peer->qos_info, peer->wmm_capable,
+				       peer->ext_capab, peer->ext_capab_len,
 				       peer->supp_channels,
 				       peer->supp_channels_len,
 				       peer->supp_oper_classes,
@@ -1858,6 +1866,8 @@
 		wpa_printf(MSG_DEBUG, "TDLS: Testing concurrent initiation of "
 			   "TDLS setup - send own request");
 		peer->initiator = 1;
+		wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
+					NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0);
 		wpa_tdls_send_tpk_m1(sm, peer);
 	}
 
@@ -2036,10 +2046,18 @@
 	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);
 
 skip_rsn_check:
+#ifdef CONFIG_TDLS_TESTING
+	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT)
+		goto skip_add_peer;
+#endif /* CONFIG_TDLS_TESTING */
+
 	/* add supported rates, capabilities, and qos_info to the TDLS peer */
 	if (wpa_tdls_addset_peer(sm, peer, 1) < 0)
 		goto error;
 
+#ifdef CONFIG_TDLS_TESTING
+skip_add_peer:
+#endif /* CONFIG_TDLS_TESTING */
 	peer->tpk_in_progress = 1;
 
 	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
@@ -2051,7 +2069,7 @@
 	return 0;
 
 error:
-	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken,
+	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
 			    status);
 	if (peer)
 		wpa_tdls_peer_free(sm, peer);
@@ -2362,7 +2380,7 @@
 	return ret;
 
 error:
-	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
+	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 1,
 			    status);
 	wpa_tdls_disable_peer_link(sm, peer);
 	return -1;
@@ -2587,7 +2605,7 @@
 
 	/* add the peer to the driver as a "setup in progress" peer */
 	if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
-				    NULL, 0, NULL, 0, NULL, 0, NULL, 0)) {
+				    NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0)) {
 		wpa_tdls_disable_peer_link(sm, peer);
 		return -1;
 	}
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 9471071..b17fc88 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -1295,7 +1295,8 @@
 				(unsigned long) maxkeylen);
 			return -1;
 		}
-		if (aes_unwrap(sm->ptk.kek, maxkeylen / 8, key_data, gd->gtk)) {
+		if (aes_unwrap(sm->ptk.kek, 16, maxkeylen / 8, key_data,
+			       gd->gtk)) {
 			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
 				"WPA: AES unwrap failed - could not decrypt "
 				"GTK");
@@ -1503,7 +1504,7 @@
 				"WPA: No memory for AES-UNWRAP buffer");
 			return -1;
 		}
-		if (aes_unwrap(sm->ptk.kek, *key_data_len / 8,
+		if (aes_unwrap(sm->ptk.kek, 16, *key_data_len / 8,
 			       key_data, buf)) {
 			os_free(buf);
 			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 07a7bf9..63032b0 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -55,14 +55,14 @@
 	int (*send_tdls_mgmt)(void *ctx, const u8 *dst,
 			      u8 action_code, u8 dialog_token,
 			      u16 status_code, u32 peer_capab,
-			      const u8 *buf, size_t len);
+			      int initiator, const u8 *buf, size_t len);
 	int (*tdls_oper)(void *ctx, int oper, const u8 *peer);
 	int (*tdls_peer_addset)(void *ctx, const u8 *addr, int add, u16 aid,
 				u16 capability, const u8 *supp_rates,
 				size_t supp_rates_len,
 				const struct ieee80211_ht_capabilities *ht_capab,
 				const struct ieee80211_vht_capabilities *vht_capab,
-				u8 qosinfo, const u8 *ext_capab,
+				u8 qosinfo, int wmm, const u8 *ext_capab,
 				size_t ext_capab_len, const u8 *supp_channels,
 				size_t supp_channels_len,
 				const u8 *supp_oper_classes,
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index 4a75b92..3b3c9d0 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -566,7 +566,7 @@
 		return -1;
 	}
 	gtk_len = gtk_elem_len - 19;
-	if (aes_unwrap(sm->ptk.kek, gtk_len / 8, gtk_elem + 11, gtk)) {
+	if (aes_unwrap(sm->ptk.kek, 16, gtk_len / 8, gtk_elem + 11, gtk)) {
 		wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
 			   "decrypt GTK");
 		return -1;
@@ -645,7 +645,8 @@
 		return -1;
 	}
 
-	if (aes_unwrap(sm->ptk.kek, WPA_IGTK_LEN / 8, igtk_elem + 9, igtk)) {
+	if (aes_unwrap(sm->ptk.kek, 16, WPA_IGTK_LEN / 8, igtk_elem + 9, igtk))
+	{
 		wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
 			   "decrypt IGTK");
 		return -1;
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index e20e9da..839b545 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -268,12 +268,14 @@
 static inline int wpa_sm_send_tdls_mgmt(struct wpa_sm *sm, const u8 *dst,
 					u8 action_code, u8 dialog_token,
 					u16 status_code, u32 peer_capab,
-					const u8 *buf, size_t len)
+					int initiator, const u8 *buf,
+					size_t len)
 {
 	if (sm->ctx->send_tdls_mgmt)
 		return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code,
 					       dialog_token, status_code,
-					       peer_capab, buf, len);
+					       peer_capab, initiator, buf,
+					       len);
 	return -1;
 }
 
@@ -291,16 +293,16 @@
 			size_t supp_rates_len,
 			const struct ieee80211_ht_capabilities *ht_capab,
 			const struct ieee80211_vht_capabilities *vht_capab,
-			u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len,
-			const u8 *supp_channels, size_t supp_channels_len,
-			const u8 *supp_oper_classes,
+			u8 qosinfo, int wmm, const u8 *ext_capab,
+			size_t ext_capab_len, const u8 *supp_channels,
+			size_t supp_channels_len, const u8 *supp_oper_classes,
 			size_t supp_oper_classes_len)
 {
 	if (sm->ctx->tdls_peer_addset)
 		return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
 						 aid, capability, supp_rates,
 						 supp_rates_len, ht_capab,
-						 vht_capab, qosinfo,
+						 vht_capab, qosinfo, wmm,
 						 ext_capab, ext_capab_len,
 						 supp_channels,
 						 supp_channels_len,
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index 2329033..93e8cf6 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -549,7 +549,7 @@
 			ie->ht_capabilities_len = pos[1];
 		} else if (*pos == WLAN_EID_VHT_AID) {
 			if (pos[1] >= 2)
-				ie->aid = WPA_GET_LE16(pos + 2);
+				ie->aid = WPA_GET_LE16(pos + 2) & 0x3fff;
 		} else if (*pos == WLAN_EID_VHT_CAP) {
 			ie->vht_capabilities = pos + 2;
 			ie->vht_capabilities_len = pos[1];
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index f9aa807..7c93498 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -513,7 +513,7 @@
 	}
 	if (ssid->frequency == 0)
 		ssid->frequency = 2462; /* default channel 11 */
-	params.freq = ssid->frequency;
+	params.freq.freq = ssid->frequency;
 
 	params.wpa_proto = ssid->proto;
 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 54cd1ec..98d3ce4 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -6437,7 +6437,7 @@
 			wpa_s->vendor_elem[frame] = NULL;
 		} else {
 			os_memmove(ie, ie + len,
-				   wpabuf_len(wpa_s->vendor_elem[frame]) - len);
+				   end - (ie + len));
 			wpa_s->vendor_elem[frame]->used -= len;
 		}
 		os_free(buf);
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 3d22552..5e58c5b 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2961,6 +2961,10 @@
 	  wpas_dbus_getter_process_credentials,
 	  wpas_dbus_setter_process_credentials
 	},
+	{ "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
+	  wpas_dbus_getter_config_methods,
+	  wpas_dbus_setter_config_methods
+	},
 #endif /* CONFIG_WPS */
 #ifdef CONFIG_P2P
 	{ "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 51cf5f3..f6a83cd 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -298,6 +298,14 @@
 						 DBusError *error,
 						 void *user_data);
 
+dbus_bool_t wpas_dbus_getter_config_methods(DBusMessageIter *iter,
+					    DBusError *error,
+					    void *user_data);
+
+dbus_bool_t wpas_dbus_setter_config_methods(DBusMessageIter *iter,
+					    DBusError *error,
+					    void *user_data);
+
 DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
 					      struct wpa_supplicant *wpa_s);
 DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
index 4ad5e7e..8ecf7db 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -389,3 +389,60 @@
 
 	return TRUE;
 }
+
+
+/**
+ * wpas_dbus_getter_config_methods - Get current WPS configuration methods
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Getter for "ConfigMethods" property. Returned boolean will be true if
+ * providing the relevant string worked, or false otherwise.
+ */
+dbus_bool_t wpas_dbus_getter_config_methods(DBusMessageIter *iter,
+					    DBusError *error,
+					    void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	char *methods = wpa_s->conf->config_methods;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						&methods, error);
+}
+
+
+/**
+ * wpas_dbus_setter_config_methods - Set WPS configuration methods
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Setter for "ConfigMethods" property. Sets the methods string, apply such
+ * change and returns true on success. Returns false otherwise.
+ */
+dbus_bool_t wpas_dbus_setter_config_methods(DBusMessageIter *iter,
+					    DBusError *error,
+					    void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	char *methods, *new_methods;
+
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
+					      &methods))
+		return FALSE;
+
+	new_methods = os_strdup(methods);
+	if (!new_methods)
+		return FALSE;
+
+	os_free(wpa_s->conf->config_methods);
+	wpa_s->conf->config_methods = new_methods;
+
+	wpa_s->conf->changed_parameters |= CFG_CHANGED_CONFIG_METHODS;
+	wpa_supplicant_update_config(wpa_s);
+
+	return TRUE;
+}
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index cba32a9..649de9b 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -532,14 +532,14 @@
 static inline int wpa_drv_send_tdls_mgmt(struct wpa_supplicant *wpa_s,
 					 const u8 *dst, u8 action_code,
 					 u8 dialog_token, u16 status_code,
-					 u32 peer_capab, const u8 *buf,
-					 size_t len)
+					 u32 peer_capab, int initiator,
+					 const u8 *buf, size_t len)
 {
 	if (wpa_s->driver->send_tdls_mgmt) {
 		return wpa_s->driver->send_tdls_mgmt(wpa_s->drv_priv, dst,
 						     action_code, dialog_token,
 						     status_code, peer_capab,
-						     buf, len);
+						     initiator, buf, len);
 	}
 	return -1;
 }
diff --git a/wpa_supplicant/eap_proxy_dummy.mak b/wpa_supplicant/eap_proxy_dummy.mak
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/wpa_supplicant/eap_proxy_dummy.mak
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 081b585..985fa6e 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -582,7 +582,7 @@
 }
 
 
-static int ht_supported(const struct hostapd_hw_modes *mode)
+int ht_supported(const struct hostapd_hw_modes *mode)
 {
 	if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) {
 		/*
@@ -600,7 +600,7 @@
 }
 
 
-static int vht_supported(const struct hostapd_hw_modes *mode)
+int vht_supported(const struct hostapd_hw_modes *mode)
 {
 	if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) {
 		/*
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index d2e839d..e596468 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -331,7 +331,8 @@
 		if (wpa_s->global->p2p == NULL &&
 		    (wpa_s->drv_flags &
 		     WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
-		    wpas_p2p_add_p2pdev_interface(wpa_s) < 0)
+		    wpas_p2p_add_p2pdev_interface(wpa_s, iface->conf_p2p_dev) <
+		    0)
 			exitcode = -1;
 #endif /* CONFIG_P2P */
 	}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index ca45b5b..640154c 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3786,7 +3786,8 @@
 }
 
 
-int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s)
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
+				  const char *conf_p2p_dev)
 {
 	struct wpa_interface iface;
 	struct wpa_supplicant *p2pdev_wpa_s;
@@ -3817,8 +3818,8 @@
 	 * If a P2P Device configuration file was given, use it as the interface
 	 * configuration file (instead of using parent's configuration file.
 	 */
-	if (wpa_s->conf_p2p_dev) {
-		iface.confname = wpa_s->conf_p2p_dev;
+	if (conf_p2p_dev) {
+		iface.confname = conf_p2p_dev;
 		iface.ctrl_interface = NULL;
 	} else {
 		iface.confname = wpa_s->confname;
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index d79ec03..8e23c18 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -16,7 +16,8 @@
 struct p2p_channels;
 struct wps_event_fail;
 
-int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s);
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
+				  const char *conf_p2p_dev);
 struct wpa_supplicant * wpas_get_p2p_go_iface(struct wpa_supplicant *wpa_s,
 					      const u8 *ssid, size_t ssid_len);
 struct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index e4f2d12..36b4f87 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -742,7 +742,7 @@
 	params.bssid = bssid;
 	params.ssid = wpa_s->sme.ssid;
 	params.ssid_len = wpa_s->sme.ssid_len;
-	params.freq = wpa_s->sme.freq;
+	params.freq.freq = wpa_s->sme.freq;
 	params.bg_scan_period = wpa_s->current_ssid ?
 		wpa_s->current_ssid->bg_scan_period : -1;
 	params.wpa_ie = wpa_s->sme.assoc_req_ie_len ?
@@ -780,7 +780,7 @@
 	wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
 		" (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
 		params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "",
-		params.freq);
+		params.freq.freq);
 
 	wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index d128992..397d2f6 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -406,11 +406,6 @@
 	os_free(wpa_s->confanother);
 	wpa_s->confanother = NULL;
 
-#ifdef CONFIG_P2P
-	os_free(wpa_s->conf_p2p_dev);
-	wpa_s->conf_p2p_dev = NULL;
-#endif /* CONFIG_P2P */
-
 	wpa_sm_set_eapol(wpa_s->wpa, NULL);
 	eapol_sm_deinit(wpa_s->eapol);
 	wpa_s->eapol = NULL;
@@ -1843,7 +1838,7 @@
 				   MAC2STR(bss->bssid), bss->freq,
 				   ssid->bssid_set);
 			params.bssid = bss->bssid;
-			params.freq = bss->freq;
+			params.freq.freq = bss->freq;
 		}
 		params.bssid_hint = bss->bssid;
 		params.freq_hint = bss->freq;
@@ -1859,8 +1854,23 @@
 	}
 
 	if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
-	    params.freq == 0)
-		params.freq = ssid->frequency; /* Initial channel for IBSS */
+	    params.freq.freq == 0) {
+		enum hostapd_hw_mode hw_mode;
+		u8 channel;
+
+		params.freq.freq = ssid->frequency;
+
+		hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
+		for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
+			if (wpa_s->hw.modes[i].mode == hw_mode) {
+				struct hostapd_hw_modes *mode;
+
+				mode = &wpa_s->hw.modes[i];
+				params.freq.ht_enabled = ht_supported(mode);
+				break;
+			}
+		}
+	}
 
 	if (ssid->mode == WPAS_MODE_IBSS) {
 		if (ssid->beacon_int)
@@ -1944,13 +1954,12 @@
 	if (wpa_s->num_multichan_concurrent < 2) {
 		int freq, num;
 		num = get_shared_radio_freqs(wpa_s, &freq, 1);
-		if (num > 0 && freq > 0 && freq != params.freq) {
+		if (num > 0 && freq > 0 && freq != params.freq.freq) {
 			wpa_printf(MSG_DEBUG,
 				   "Assoc conflicting freq found (%d != %d)",
-				   freq, params.freq);
-			if (wpas_p2p_handle_frequency_conflicts(wpa_s,
-								params.freq,
-								ssid) < 0)
+				   freq, params.freq.freq);
+			if (wpas_p2p_handle_frequency_conflicts(
+				    wpa_s, params.freq.freq, ssid) < 0)
 				return;
 		}
 	}
@@ -3601,13 +3610,6 @@
 		wpa_s->confanother = os_rel2abs_path(iface->confanother);
 		wpa_config_read(wpa_s->confanother, wpa_s->conf);
 
-#ifdef CONFIG_P2P
-		wpa_s->conf_p2p_dev = os_rel2abs_path(iface->conf_p2p_dev);
-#ifndef ANDROID_P2P
-		wpa_config_read(wpa_s->conf_p2p_dev, wpa_s->conf);
-#endif
-#endif /* CONFIG_P2P */
-
 		/*
 		 * Override ctrl_interface and driver_param if set on command
 		 * line.
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index f941923..cbe3e49 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -67,7 +67,7 @@
 
 #ifdef CONFIG_P2P
 	/**
-	 * conf_p2p_dev - Additional configuration file used to hold the
+	 * conf_p2p_dev - Configuration file used to hold the
 	 * P2P Device configuration parameters.
 	 *
 	 * This can also be %NULL. In such a case, if a P2P Device dedicated
@@ -408,10 +408,6 @@
 	char *confname;
 	char *confanother;
 
-#ifdef CONFIG_P2P
-	char *conf_p2p_dev;
-#endif /* CONFIG_P2P */
-
 	struct wpa_config *conf;
 	int countermeasures;
 	struct os_reltime last_michael_mic_error;
@@ -993,6 +989,8 @@
 int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s);
 struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
 					     struct wpa_ssid **selected_ssid);
+int ht_supported(const struct hostapd_hw_modes *mode);
+int vht_supported(const struct hostapd_hw_modes *mode);
 
 /* eap_register.c */
 int eap_register_methods(void);
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 09b5961..38279b1 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -580,11 +580,13 @@
 static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
 					 u8 action_code, u8 dialog_token,
 					 u16 status_code, u32 peer_capab,
-					 const u8 *buf, size_t len)
+					 int initiator, const u8 *buf,
+					 size_t len)
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token,
-				      status_code, peer_capab, buf, len);
+				      status_code, peer_capab, initiator, buf,
+				      len);
 }
 
 
@@ -600,7 +602,7 @@
 	const u8 *supp_rates, size_t supp_rates_len,
 	const struct ieee80211_ht_capabilities *ht_capab,
 	const struct ieee80211_vht_capabilities *vht_capab,
-	u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len,
+	u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len,
 	const u8 *supp_channels, size_t supp_channels_len,
 	const u8 *supp_oper_classes, size_t supp_oper_classes_len)
 {
@@ -615,10 +617,10 @@
 	params.flags = WPA_STA_TDLS_PEER | WPA_STA_AUTHORIZED;
 
 	/*
-	 * TDLS Setup frames do not contain WMM IEs, hence need to depend on
-	 * qosinfo to check if the peer is WMM capable.
+	 * Don't rely only on qosinfo for WMM capability. It may be 0 even when
+	 * present. Allow the WMM IE to also indicate QoS support.
 	 */
-	if (qosinfo)
+	if (wmm || qosinfo)
 		params.flags |= WPA_STA_WMM;
 
 	params.ht_capabilities = ht_capab;