diff options
author | Roger Wang <wangroger@google.com> | 2022-05-07 12:52:09 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2022-05-07 12:52:09 +0000 |
commit | 11a0b3471a2e54dae01f40a9d544fe46852f92ed (patch) | |
tree | e82b1876cbb51d7212ed653454b219d075ec61f2 | |
parent | 9d7720d3ef7dba6e4d41ddba4f20af947fbbd5be (diff) | |
parent | 1470908c0973e52879dfd304426d3a4904e249b0 (diff) | |
download | wpa_supplicant_8-11a0b3471a2e54dae01f40a9d544fe46852f92ed.tar.gz |
Merge changes from topic "cross_AKM" into tm-dev
* changes:
Multi AKM(SAE+WPA2PSK) plumb from connect command
Adding support for Transition Disable policy setting
-rw-r--r-- | src/common/brcm_vendor.h | 6 | ||||
-rw-r--r-- | src/common/ieee802_11_defs.h | 5 | ||||
-rw-r--r-- | src/drivers/driver.h | 9 | ||||
-rw-r--r-- | src/drivers/driver_nl80211.c | 102 | ||||
-rw-r--r-- | wpa_supplicant/events.c | 52 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant.c | 23 | ||||
-rw-r--r-- | wpa_supplicant/wpas_glue.c | 11 |
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 acd122d5..a2c48423 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 */ +#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) @@ -6381,6 +6401,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"); @@ -6443,7 +6479,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)) @@ -6494,7 +6535,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; @@ -6603,7 +6649,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 @@ -12018,6 +12069,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; @@ -12171,6 +12235,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 ae494f6e..b724eec0 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 a995f261..008ec08a 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(¶ms, 0, sizeof(params)); + params.td_policy = bitmap; + wpa_drv_update_connect_params(wpa_s, ¶ms, WPA_DRV_UPDATE_TD_POLICY); + } +#endif /* CONFIG_DRIVER_NL80211_BRCM */ + wpas_notify_transition_disable(wpa_s, ssid, bitmap); if (!changed) |