aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-08 01:06:51 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-08 01:06:51 +0000
commit42e2866087a46e6138fc04d2af3f85b5cbbcd43a (patch)
tree875c2fac08a3c27b18e5b908451b9ccbc6a08b56
parent00ccce5b6fedae5d51ccec90d40d3a97632c12c5 (diff)
parentaf231dafd7da77952a4f1d901577b73b071453a2 (diff)
downloadwpa_supplicant_8-42e2866087a46e6138fc04d2af3f85b5cbbcd43a.tar.gz
Snap for 8557720 from af231dafd7da77952a4f1d901577b73b071453a2 to tm-qpr1-release
Change-Id: Ib7cd51e3148f858c46b71976147c674e4ac6e46e
-rw-r--r--src/common/brcm_vendor.h6
-rw-r--r--src/common/ieee802_11_defs.h5
-rw-r--r--src/drivers/driver.h9
-rw-r--r--src/drivers/driver_nl80211.c102
-rw-r--r--wpa_supplicant/events.c52
-rw-r--r--wpa_supplicant/wpa_supplicant.c23
-rw-r--r--wpa_supplicant/wpas_glue.c11
7 files changed, 200 insertions, 8 deletions
diff --git a/src/common/brcm_vendor.h b/src/common/brcm_vendor.h
index 03a178e5..d77b0076 100644
--- a/src/common/brcm_vendor.h
+++ b/src/common/brcm_vendor.h
@@ -62,7 +62,8 @@ enum brcm_nl80211_vendor_subcmds {
BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS = 7,
BRCM_VENDOR_SCMD_SET_START_AP_PARAMS = 8,
BRCM_VENDOR_SCMD_ACS = 9,
- BRCM_VENDOR_SCMD_MAX = 10
+ BRCM_VENDOR_SCMD_SET_TD_POLICY = 10,
+ BRCM_VENDOR_SCMD_MAX = 11
};
/**
@@ -156,7 +157,8 @@ enum brcm_wlan_vendor_attr {
BRCM_ATTR_DRIVER_CMD = 0,
BRCM_ATTR_DRIVER_KEY_PMK = 1,
BRCM_ATTR_DRIVER_MAC_ADDR = 3,
- BRCM_ATTR_DRIVER_AFTER_LAST = 5,
+ BRCM_ATTR_DRIVER_TD_POLICY = 5,
+ BRCM_ATTR_DRIVER_AFTER_LAST = 6,
BRCM_ATTR_DRIVER_MAX = BRCM_ATTR_DRIVER_AFTER_LAST - 1,
};
#endif /* BRCM_VENDOR_H */
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 5ee691bc..4300ae54 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -2529,4 +2529,9 @@ enum dscp_policy_request_type {
#define WFA_CAPA_QM_DSCP_POLICY BIT(0)
#define WFA_CAPA_QM_UNSOLIC_DSCP BIT(1)
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+#define WPA_KEY_MGMT_CROSS_AKM_ROAM (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK)
+#define IS_CROSS_AKM_ROAM_KEY_MGMT(key_mgmt) \
+ ((key_mgmt & WPA_KEY_MGMT_CROSS_AKM_ROAM) == WPA_KEY_MGMT_CROSS_AKM_ROAM)
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
#endif /* IEEE802_11_DEFS_H */
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 85be4c38..8b92e129 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1203,6 +1203,12 @@ struct wpa_driver_associate_params {
* 2 = both hunting-and-pecking loop and hash-to-element enabled
*/
int sae_pwe;
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ /**
+ * td_policy - Transition Disable Policy
+ */
+ u32 td_policy;
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
};
enum hide_ssid {
@@ -2495,6 +2501,9 @@ enum wpa_drv_update_connect_params_mask {
WPA_DRV_UPDATE_ASSOC_IES = BIT(0),
WPA_DRV_UPDATE_FILS_ERP_INFO = BIT(1),
WPA_DRV_UPDATE_AUTH_TYPE = BIT(2),
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ WPA_DRV_UPDATE_TD_POLICY = BIT(3),
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
};
/**
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index af76dd4a..5d79db65 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -199,7 +199,9 @@ static int nl80211_put_mesh_config(struct nl_msg *msg,
#endif /* CONFIG_MESH */
static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
u16 reason);
-
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+static int nl80211_set_td_policy(void *priv, u32 td_policy);
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
/* Converts nl80211_chan_width to a common format */
enum chan_width convert2width(int width)
@@ -3241,6 +3243,24 @@ fail:
}
#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+static int wpa_cross_akm_key_mgmt_to_suites(unsigned int key_mgmt_suites, u32 suites[],
+ int max_suites)
+{
+ int num_suites = 0;
+
+#define __AKM_TO_SUITES_ARRAY(a, b) \
+ if (num_suites < max_suites && \
+ (key_mgmt_suites & (WPA_KEY_MGMT_ ## a))) \
+ suites[num_suites++] = (RSN_AUTH_KEY_MGMT_ ## b)
+ __AKM_TO_SUITES_ARRAY(PSK, PSK_OVER_802_1X);
+ __AKM_TO_SUITES_ARRAY(SAE, SAE);
+#undef __AKM_TO_SUITES_ARRAY
+
+ return num_suites;
+}
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
#ifdef CONFIG_DRIVER_NL80211_QCA
static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv,
const u8 *key, size_t key_len)
@@ -6383,6 +6403,22 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
return -1;
}
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ if (IS_CROSS_AKM_ROAM_KEY_MGMT(params->key_mgmt_suite)) {
+ int num_suites;
+ u32 suites[NL80211_MAX_NR_AKM_SUITES];
+
+ wpa_printf(MSG_INFO, "nl80211: key_mgmt_suites=0x%x",
+ params->key_mgmt_suite);
+ num_suites = wpa_cross_akm_key_mgmt_to_suites(params->key_mgmt_suite,
+ suites, ARRAY_SIZE(suites));
+ if (num_suites &&
+ nla_put(msg, NL80211_ATTR_AKM_SUITES, num_suites * sizeof(u32), suites)) {
+ wpa_printf(MSG_ERROR, "Updating multi akm_suite failed");
+ return -1;
+ }
+ }
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
if (params->req_handshake_offload &&
(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X)) {
wpa_printf(MSG_DEBUG, " * WANT_1X_4WAY_HS");
@@ -6445,7 +6481,12 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
nl80211_put_fils_connect_params(drv, params, msg) != 0)
return -1;
- if ((params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
+ if ((
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ (params->key_mgmt_suite & WPA_KEY_MGMT_SAE) ||
+#else
+ params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE) &&
(!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) &&
nla_put_flag(msg, NL80211_ATTR_EXTERNAL_AUTH_SUPPORT))
@@ -6496,7 +6537,12 @@ static int wpa_driver_nl80211_try_connect(
goto fail;
#ifdef CONFIG_SAE
- if ((params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
+ if ((
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ (params->key_mgmt_suite & WPA_KEY_MGMT_SAE) ||
+#else
+ params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE) &&
nl80211_put_sae_pwe(msg, params->sae_pwe) < 0)
goto fail;
@@ -6605,7 +6651,12 @@ static int wpa_driver_nl80211_associate(
if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
return -1;
- if (params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
+ if (
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ (params->key_mgmt_suite & WPA_KEY_MGMT_SAE) ||
+#else
+ params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE)
bss->use_nl_connect = 1;
else
@@ -12022,6 +12073,19 @@ static int nl80211_update_connection_params(
if (drv->capa.flags & WPA_DRIVER_FLAGS_SME)
return 0;
+ /* Handle any connection param update here which might receive kernel handling in future */
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ if (mask & WPA_DRV_UPDATE_TD_POLICY) {
+ ret = nl80211_set_td_policy(priv, params->td_policy);
+ if (ret) {
+ wpa_dbg(drv->ctx, MSG_DEBUG,
+ "nl80211: Update connect params command failed: ret=%d (%s)",
+ ret, strerror(-ret));
+ }
+ return ret;
+ }
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_UPDATE_CONNECT_PARAMS);
if (!msg)
goto fail;
@@ -12175,6 +12239,36 @@ static int nl80211_dpp_listen(void *priv, bool enable)
}
#endif /* CONFIG_DPP */
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+static int nl80211_set_td_policy(void *priv, u32 td_policy)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ int ret;
+ struct nlattr *params;
+
+ if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, BRCM_VENDOR_SCMD_SET_TD_POLICY) ||
+ !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+ (nla_put_u32(msg, BRCM_ATTR_DRIVER_TD_POLICY, td_policy))) {
+ nl80211_nlmsg_clear(msg);
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
+ nla_nest_end(msg, params);
+ wpa_printf(MSG_DEBUG, "nl80211: Transition Disable Policy %d\n", td_policy);
+
+ ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1, NULL, NULL);
+ if (ret) {
+ wpa_printf(MSG_DEBUG, "nl80211: Transition Disable setting failed: ret=%d (%s)",
+ ret, strerror(-ret));
+ }
+
+ return ret;
+}
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
#ifdef CONFIG_TESTING_OPTIONS
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index e6828959..35467ce9 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1319,6 +1319,9 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
#ifdef CONFIG_SAE
if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
wpa_s->conf->sae_pwe != 3 && wpa_key_mgmt_sae(ssid->key_mgmt) &&
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ !(wpa_key_mgmt_wpa_psk_no_sae(ssid->key_mgmt)) &&
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG,
@@ -2893,6 +2896,9 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
const u8 *p;
u8 bssid[ETH_ALEN];
bool bssid_known;
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ struct wpa_ie_data ie;
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0;
@@ -3017,6 +3023,52 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
if (!found_x && data->assoc_info.req_ies)
wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ /* The WPA/RSN IE has been updated at this point. Since the Firmware could have roamed
+ * to a different security type, update the current supplicant configuration to use the AKM
+ * and pairwise suites from the assoc IE passed by the driver.
+ */
+ if (wpas_driver_bss_selection(wpa_s)) {
+ if (!(wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0)) {
+ /* Check if firmware has roamed to a different security network */
+ if(wpa_s->key_mgmt != ie.key_mgmt) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Update to AKM suite 0x%x from Assoc IE",
+ ie.key_mgmt);
+ wpa_s->key_mgmt = ie.key_mgmt;
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
+
+ if (wpa_key_mgmt_wpa_psk_no_sae(wpa_s->key_mgmt)) {
+ /* Restore PMK as it can get overwritten if the previous
+ * association was to 802.1X.
+ */
+ if ((!(wpa_s->drv_flags &
+ WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK)) &&
+ (wpa_s->current_ssid) &&
+ (wpa_s->current_ssid->psk_set)) {
+ if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
+ wpa_dbg(wpa_s, MSG_ERROR, "Failed to get "
+ "BSSID");
+ wpa_supplicant_deauthenticate(
+ wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+ return -1;
+ }
+ wpa_sm_set_pmk(wpa_s->wpa, wpa_s->current_ssid->psk,
+ PMK_LEN, NULL, bssid);
+ }
+ }
+ }
+ if(wpa_s->pairwise_cipher != ie.pairwise_cipher) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Update to pairwise cipher suite 0x%x "
+ "from Assoc IE", ie.pairwise_cipher);
+ wpa_s->pairwise_cipher = ie.pairwise_cipher;
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
+ wpa_s->pairwise_cipher);
+ }
+ // TODO: Notify the framework about security type change b/230766005
+ }
+ }
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
#ifdef CONFIG_FILS
#ifdef CONFIG_SME
if ((wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 139907f1..99af85e0 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1891,6 +1891,15 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DENY_PTK0_REKEY, 0);
}
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ if ((wpa_s->key_mgmt & WPA_KEY_MGMT_CROSS_AKM_ROAM) &&
+ IS_CROSS_AKM_ROAM_KEY_MGMT(ssid->key_mgmt)) {
+ wpa_s->key_mgmt = WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK;
+ wpa_dbg(wpa_s, MSG_INFO,
+ "WPA: Updating to KEY_MGMT SAE+PSK for seamless roaming");
+ }
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
return 0;
}
@@ -3904,7 +3913,12 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
#endif /* CONFIG_WEP */
if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
- (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
+ (
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ (params.key_mgmt_suite & WPA_KEY_MGMT_PSK) ||
+#else
+ params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
params.passphrase = ssid->passphrase;
if (ssid->psk_set)
@@ -3929,7 +3943,12 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
else
params.req_key_mgmt_offload = 1;
- if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
+ if ((
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ (params.key_mgmt_suite & WPA_KEY_MGMT_PSK) ||
+#else
+ params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
ssid->psk_set)
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 16799093..85028f00 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -1366,6 +1366,17 @@ static void wpa_supplicant_transition_disable(void *_wpa_s, u8 bitmap)
changed = 1;
}
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ /* driver call for transition disable */
+ {
+ struct wpa_driver_associate_params params;
+
+ os_memset(&params, 0, sizeof(params));
+ params.td_policy = bitmap;
+ wpa_drv_update_connect_params(wpa_s, &params, WPA_DRV_UPDATE_TD_POLICY);
+ }
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
wpas_notify_transition_disable(wpa_s, ssid, bitmap);
if (!changed)