aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2014-10-07 13:15:23 -0700
committerDmitry Shmidt <dimitrysh@google.com>2014-10-07 13:23:26 -0700
commit9ead16e203b81d44a2d84eadc2901ceeb7daf805 (patch)
tree773ef2cb584269ca34349940e77a437e7aaab54e /src
parent3bbb64943b5c815d6b22b56f3255d6651294adbe (diff)
downloadandroid_external_wpa_supplicant_8-9ead16e203b81d44a2d84eadc2901ceeb7daf805.tar.gz
android_external_wpa_supplicant_8-9ead16e203b81d44a2d84eadc2901ceeb7daf805.tar.bz2
android_external_wpa_supplicant_8-9ead16e203b81d44a2d84eadc2901ceeb7daf805.zip
Cumulative patch from commit d5fe4e6c18d94465e8fb4527d51df6e8539c4d6a
d5fe4e6 Reserve QCA vendor specific nl80211 commands 34..49 a256506 AES: Extend key wrap implementation to support longer data eefec1e AES: Extend key wrap design to support longer AES keys 98a1571 OpenSSL: Clean up one part from the BoringSSL patch a857296 Support building with BoringSSL 1236eda Android: Remove ctrl_interface=wlan0 from config template 9ffd512 Android: Set pmf=1 to default template 45d8501 Fix out of bounds memory access when removing vendor elements a61fcc1 Clean up authenticator PMKSA cache implementation cb129db Clear PMKSA cache entry data when freeing them 8c8d26a Remove unnecessary PMKSA cache freeing step 9c82990 Fix authenticator OKC fetch from PMKSA cache to avoid infinite loop 47ea24c Fix PMKSA cache timeout from Session-Timeout in WPA/WPA2 cases dc152f3 wpa_supplicant: Enable HT for IBSS 4ec6837 wpa_supplicant: Use hostapd_freq_params in assoc_params 43f02e6 wpa_ctrl: Update wpa_ctrl_recv() documentation for non-block behavior 1274ec2 dbus: Add an interface configuration entry to set the WPS methods 3e0272c nl80211: Re-read MAC address on RTM_NEWLINK 5dfbd72 nl80211: Add get_bss_ifindex() helper f1a6131 P2P: Use only the -m config for P2P management device 08d7665 TDLS: Use WMM IE for propagating peer WMM capability 17729b0 TDLS: Fix concurrent setup test for mac80211 drivers 984dadc TDLS: Set the initiator during tdls_mgmt operations 01cb5df Sync with wireless-testing.git include/uapi/linux/nl80211.h ca3c6b4 nl80211: Fix compatibility with older version of libnl d76426c TDLS: Filter AID value properly for VHT peers Change-Id: Ia2156628a590c502d9111de2727da642ff435d9a Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/ap/ieee802_1x.c10
-rw-r--r--src/ap/pmksa_cache_auth.c65
-rw-r--r--src/ap/sta_info.h3
-rw-r--r--src/ap/wpa_auth.c3
-rw-r--r--src/ap/wpa_auth_ft.c22
-rw-r--r--src/common/qca-vendor.h2
-rw-r--r--src/common/wpa_ctrl.h7
-rw-r--r--src/crypto/aes-unwrap.c19
-rw-r--r--src/crypto/aes-wrap.c20
-rw-r--r--src/crypto/aes_wrap.h8
-rw-r--r--src/crypto/crypto_openssl.c8
-rw-r--r--src/crypto/tls_openssl.c34
-rw-r--r--src/drivers/driver.h47
-rw-r--r--src/drivers/driver_nl80211.c88
-rw-r--r--src/drivers/driver_test.c2
-rw-r--r--src/drivers/driver_wext.c3
-rw-r--r--src/drivers/nl80211_copy.h150
-rw-r--r--src/eap_common/eap_pwd_common.c2
-rw-r--r--src/eap_server/eap_server_fast.c8
-rw-r--r--src/pae/ieee802_1x_kay.c4
-rw-r--r--src/rsn_supp/pmksa_cache.c2
-rw-r--r--src/rsn_supp/tdls.c56
-rw-r--r--src/rsn_supp/wpa.c5
-rw-r--r--src/rsn_supp/wpa.h4
-rw-r--r--src/rsn_supp/wpa_ft.c5
-rw-r--r--src/rsn_supp/wpa_i.h14
-rw-r--r--src/rsn_supp/wpa_ie.c2
27 files changed, 430 insertions, 163 deletions
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index e4681e90..2d09b67b 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -1622,6 +1622,9 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
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 @@ static void ieee802_1x_finished(struct hostapd_data *hapd,
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 @@ static void ieee802_1x_finished(struct hostapd_data *hapd,
#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 4720b59c..9de4cffe 100644
--- a/src/ap/pmksa_cache_auth.c
+++ b/src/ap/pmksa_cache_auth.c
@@ -37,14 +37,12 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa);
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 @@ void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
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 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
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 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
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 @@ void pmksa_cache_auth_deinit(struct rsn_pmksa_cache *pmksa)
_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 @@ pmksa_cache_auth_get(struct rsn_pmksa_cache *pmksa,
{
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 * pmksa_cache_get_okc(
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 03db98f6..faf32d85 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -60,6 +60,7 @@ struct sta_info {
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 @@ struct sta_info {
#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 2bb8aab8..1a16b5c8 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1390,7 +1390,8 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
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 8a6ca71c..781f15fb 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -344,7 +344,8 @@ static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm,
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 @@ static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len)
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 @@ static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
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 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
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 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
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 @@ static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth,
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 @@ static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth,
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 @@ static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
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 de0b222b..ad3bdfd6 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -60,7 +60,7 @@ enum qca_nl80211_vendor_subcmds {
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 d91594e3..4812f8df 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -345,9 +345,10 @@ int wpa_ctrl_detach(struct wpa_ctrl *ctrl);
* @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 9dd51602..ec793d9d 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 @@ int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain)
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 89d6f94b..7ed34e80 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 @@ int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
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 @@ int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
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 0433c043..6b3727c7 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 8876ebf2..b4c59d18 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 @@ void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
}
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 @@ static const EVP_CIPHER * aes_get_evp_cipher(size_t keylen)
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 @@ struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
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 d2d66003..e1534224 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 @@ void tls_deinit(void *ssl_ctx)
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 @@ static int tls_match_altsubject_component(X509 *cert, int type,
{
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 @@ static int tls_match_suffix(X509 *cert, const char *match)
GENERAL_NAME *gen;
void *ext;
int i;
+ stack_index_t j;
int dns_name = 0;
X509_NAME *name;
@@ -1211,8 +1225,8 @@ static int tls_match_suffix(X509 *cert, const char *match)
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 @@ static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
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 @@ unsigned int tls_capabilities(void *tls_ctx)
* 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 501314bb..6af72943 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -411,6 +411,25 @@ enum wps_mode {
*/
};
+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 @@ struct wpa_driver_associate_params {
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 @@ struct hostapd_sta_add_params {
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 @@ struct wpa_driver_ops {
* @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 @@ struct wpa_driver_ops {
*/
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 5c922a05..d0304743 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -331,7 +331,7 @@ struct wpa_driver_nl80211_data {
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 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
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 int is_p2p_net_interface(enum nl80211_iftype nlmode)
}
+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 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
"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 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
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 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
"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 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
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 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
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 @@ static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
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 @@ retry:
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 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
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(struct i802_bss *bss,
}
-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 @@ nla_put_failure:
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 @@ static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
*/
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 3608b522..66edfa73 100644
--- a/src/drivers/driver_test.c
+++ b/src/drivers/driver_test.c
@@ -1478,7 +1478,7 @@ static int wpa_driver_test_associate(
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 459ac481..1b3a757b 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -2119,7 +2119,8 @@ int wpa_driver_wext_associate(void *priv,
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 406010d4..4b28dc07 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 @@ enum nl80211_commands {
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 @@ enum nl80211_commands {
* 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 @@ enum nl80211_commands {
* 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 @@ enum nl80211_commands {
* 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 @@ enum nl80211_attrs {
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 @@ enum nl80211_sta_bss_param {
* 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 @@ enum nl80211_sta_info {
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 @@ enum nl80211_bss_scan_width {
* @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 @@ enum nl80211_bss_scan_width {
* 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 @@ enum nl80211_bss {
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 @@ enum nl80211_iface_limit_attrs {
* 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 @@ enum nl80211_if_combination_attrs {
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 @@ enum nl80211_ap_sme_features {
* @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 @@ enum nl80211_ap_sme_features {
* @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 @@ enum nl80211_feature_flags {
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_acl_policy {
};
/**
+ * 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 fdcff7fa..631c363f 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -106,9 +106,11 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
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 4691e722..2692bced 100644
--- a/src/eap_server/eap_server_fast.c
+++ b/src/eap_server/eap_server_fast.c
@@ -161,8 +161,8 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
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 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
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 56c195ab..b1cf32dd 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1451,7 +1451,7 @@ ieee802_1x_mka_encode_dist_sak_body(
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 @@ ieee802_1x_mka_decode_dist_sak_body(
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 b5a87fc5..885291a2 100644
--- a/src/rsn_supp/pmksa_cache.c
+++ b/src/rsn_supp/pmksa_cache.c
@@ -35,7 +35,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa);
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 93ae1432..8cb19a25 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -218,26 +218,29 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
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 @@ static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx)
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 @@ skip_ies:
/* 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 @@ skip_ftie:
* 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 @@ skip_ies:
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 @@ static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm,
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 @@ skip_ies:
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 @@ skip_rsn_ies:
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 @@ int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr)
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 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
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 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
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 @@ skip_rsn:
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 @@ skip_rsn_check:
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 @@ skip_rsn:
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 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
/* 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 94710717..b17fc88b 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -1295,7 +1295,8 @@ static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
(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 @@ static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
"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 07a7bf90..63032b02 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -55,14 +55,14 @@ struct wpa_sm_ctx {
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 4a75b926..3b3c9d0d 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -566,7 +566,7 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
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 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
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 e20e9dac..839b545b 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -268,12 +268,14 @@ static inline int wpa_sm_tdls_get_capa(struct wpa_sm *sm,
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 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
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 2329033e..93e8cf69 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -549,7 +549,7 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
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];