[wpa_supplicant] Cumulative patch from b8491ae5a
Also revert local solution for encrypted IMSI and use the upstream version.
Bug: 134177972
Test: Device boots up and connects to WPA3/OWE wifi networks, run traffic.
Test: Able to turn on/off softap, associate wifi STA, run traffic.
Test: Regression test passed (Bug: 137653009)
Change-Id: Ie34a0138a3a2039b03101c788b43acbb33f8332a
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 66a8643..c6d0298 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -305,6 +305,9 @@
#endif /* CONFIG_IEEE80211R */
} else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
int res, pmk_len;
+#ifdef CONFIG_IEEE80211R
+ u8 buf[2 * PMK_LEN];
+#endif /* CONFIG_IEEE80211R */
if (wpa_key_mgmt_sha384(sm->key_mgmt))
pmk_len = PMK_LEN_SUITE_B_192;
@@ -320,24 +323,42 @@
res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);
pmk_len = 16;
}
- } else {
-#ifdef CONFIG_IEEE80211R
- u8 buf[2 * PMK_LEN];
- if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
- {
- if (wpa_key_mgmt_sha384(sm->key_mgmt)) {
- os_memcpy(sm->xxkey, buf,
- SHA384_MAC_LEN);
- sm->xxkey_len = SHA384_MAC_LEN;
- } else {
- os_memcpy(sm->xxkey, buf + PMK_LEN,
- PMK_LEN);
- sm->xxkey_len = PMK_LEN;
- }
- os_memset(buf, 0, sizeof(buf));
- }
-#endif /* CONFIG_IEEE80211R */
}
+#ifdef CONFIG_IEEE80211R
+ if (res == 0 &&
+ eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0) {
+ if (wpa_key_mgmt_sha384(sm->key_mgmt)) {
+ os_memcpy(sm->xxkey, buf, SHA384_MAC_LEN);
+ sm->xxkey_len = SHA384_MAC_LEN;
+ } else {
+ os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
+ sm->xxkey_len = PMK_LEN;
+ }
+ forced_memzero(buf, sizeof(buf));
+ if (sm->proto == WPA_PROTO_RSN &&
+ wpa_key_mgmt_ft(sm->key_mgmt)) {
+ struct rsn_pmksa_cache_entry *sa = NULL;
+ const u8 *fils_cache_id = NULL;
+
+#ifdef CONFIG_FILS
+ if (sm->fils_cache_id_set)
+ fils_cache_id = sm->fils_cache_id;
+#endif /* CONFIG_FILS */
+ wpa_hexdump_key(MSG_DEBUG,
+ "FT: Cache XXKey/MPMK",
+ sm->xxkey, sm->xxkey_len);
+ sa = pmksa_cache_add(sm->pmksa,
+ sm->xxkey, sm->xxkey_len,
+ NULL, NULL, 0,
+ src_addr, sm->own_addr,
+ sm->network_ctx,
+ sm->key_mgmt,
+ fils_cache_id);
+ if (!sm->cur_pmksa)
+ sm->cur_pmksa = sa;
+ }
+ }
+#endif /* CONFIG_IEEE80211R */
if (res == 0) {
struct rsn_pmksa_cache_entry *sa = NULL;
const u8 *fils_cache_id = NULL;
@@ -384,6 +405,11 @@
if (!sm->cur_pmksa)
sm->cur_pmksa = sa;
+#ifdef CONFIG_IEEE80211R
+ } else if (wpa_key_mgmt_ft(sm->key_mgmt) && sm->ft_protocol) {
+ wpa_printf(MSG_DEBUG,
+ "FT: Continue 4-way handshake without PMK/PMKID for association using FT protocol");
+#endif /* CONFIG_IEEE80211R */
} else {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Failed to get master session key from "
@@ -623,7 +649,7 @@
os_memcpy(buf, &ptk->tk[16], 8);
os_memcpy(&ptk->tk[16], &ptk->tk[24], 8);
os_memcpy(&ptk->tk[24], buf, 8);
- os_memset(buf, 0, sizeof(buf));
+ forced_memzero(buf, sizeof(buf));
}
sm->tptk_set = 1;
@@ -897,7 +923,7 @@
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: Failed to set GTK to the driver "
"(Group only)");
- os_memset(gtk_buf, 0, sizeof(gtk_buf));
+ forced_memzero(gtk_buf, sizeof(gtk_buf));
return -1;
}
} else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
@@ -907,10 +933,10 @@
"WPA: Failed to set GTK to "
"the driver (alg=%d keylen=%d keyidx=%d)",
gd->alg, gd->gtk_len, gd->keyidx);
- os_memset(gtk_buf, 0, sizeof(gtk_buf));
+ forced_memzero(gtk_buf, sizeof(gtk_buf));
return -1;
}
- os_memset(gtk_buf, 0, sizeof(gtk_buf));
+ forced_memzero(gtk_buf, sizeof(gtk_buf));
if (wnm_sleep) {
sm->gtk_wnm_sleep.gtk_len = gd->gtk_len;
@@ -1016,10 +1042,10 @@
wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0))) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Failed to install GTK");
- os_memset(&gd, 0, sizeof(gd));
+ forced_memzero(&gd, sizeof(gd));
return -1;
}
- os_memset(&gd, 0, sizeof(gd));
+ forced_memzero(&gd, sizeof(gd));
return 0;
}
@@ -1688,12 +1714,12 @@
os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
os_memcpy(gd->gtk, key_data, key_data_len);
if (rc4_skip(ek, 32, 256, gd->gtk, key_data_len)) {
- os_memset(ek, 0, sizeof(ek));
+ forced_memzero(ek, sizeof(ek));
wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
"WPA: RC4 failed");
return -1;
}
- os_memset(ek, 0, sizeof(ek));
+ forced_memzero(ek, sizeof(ek));
#endif /* CONFIG_NO_RC4 */
} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
if (maxkeylen % 8) {
@@ -1842,7 +1868,7 @@
if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0) ||
wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0)
goto failed;
- os_memset(&gd, 0, sizeof(gd));
+ forced_memzero(&gd, sizeof(gd));
if (rekey) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
@@ -1861,7 +1887,7 @@
return;
failed:
- os_memset(&gd, 0, sizeof(gd));
+ forced_memzero(&gd, sizeof(gd));
wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
}
@@ -1975,12 +2001,12 @@
os_memcpy(ek, key->key_iv, 16);
os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
if (rc4_skip(ek, 32, 256, key_data, *key_data_len)) {
- os_memset(ek, 0, sizeof(ek));
+ forced_memzero(ek, sizeof(ek));
wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
"WPA: RC4 failed");
return -1;
}
- os_memset(ek, 0, sizeof(ek));
+ forced_memzero(ek, sizeof(ek));
#endif /* CONFIG_NO_RC4 */
} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
@@ -2714,6 +2740,9 @@
wpa_ft_prepare_auth_request(sm, NULL);
clear_keys = 0;
+ sm->ft_protocol = 1;
+ } else {
+ sm->ft_protocol = 0;
}
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_FILS
@@ -2778,6 +2807,7 @@
#endif /* CONFIG_FILS */
#ifdef CONFIG_IEEE80211R
sm->ft_reassoc_completed = 0;
+ sm->ft_protocol = 0;
#endif /* CONFIG_IEEE80211R */
/* Keys are not needed in the WPA state machine anymore */
@@ -3416,12 +3446,12 @@
wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
gd.gtk, gd.gtk_len);
if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) {
- os_memset(&gd, 0, sizeof(gd));
+ forced_memzero(&gd, sizeof(gd));
wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
"WNM mode");
return -1;
}
- os_memset(&gd, 0, sizeof(gd));
+ forced_memzero(&gd, sizeof(gd));
#ifdef CONFIG_IEEE80211W
} else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
const struct wpa_igtk_kde *igtk;
@@ -3851,7 +3881,7 @@
dh_ss ? wpabuf_head(dh_ss) : NULL,
dh_ss ? wpabuf_len(dh_ss) : 0,
sm->pmk, &sm->pmk_len);
- os_memset(rmsk, 0, sizeof(rmsk));
+ forced_memzero(rmsk, sizeof(rmsk));
/* Don't use DHss in PTK derivation if PMKSA caching is not
* used. */
@@ -3926,7 +3956,7 @@
sm->fils_key_auth_ap,
&sm->fils_key_auth_len);
wpabuf_free(pub);
- os_memset(ick, 0, sizeof(ick));
+ forced_memzero(ick, sizeof(ick));
return res;
fail:
wpabuf_free(pub);
@@ -4290,6 +4320,26 @@
sm->fils_session, FILS_SESSION_LEN);
}
+ if (!elems.rsn_ie) {
+ wpa_printf(MSG_DEBUG,
+ "FILS: No RSNE in (Re)Association Response");
+ /* As an interop workaround, allow this for now since IEEE Std
+ * 802.11ai-2016 did not include all the needed changes to make
+ * a FILS AP include RSNE in the frame. This workaround might
+ * eventually be removed and replaced with rejection (goto fail)
+ * to follow a strict interpretation of the standard. */
+ } else if (wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
+ sm->ap_rsn_ie, sm->ap_rsn_ie_len,
+ elems.rsn_ie - 2, elems.rsn_ie_len + 2)) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "FILS: RSNE mismatch between Beacon/Probe Response and (Re)Association Response");
+ wpa_hexdump(MSG_DEBUG, "FILS: RSNE in Beacon/Probe Response",
+ sm->ap_rsn_ie, sm->ap_rsn_ie_len);
+ wpa_hexdump(MSG_DEBUG, "FILS: RSNE in (Re)Association Response",
+ elems.rsn_ie, elems.rsn_ie_len);
+ goto fail;
+ }
+
/* TODO: FILS Public Key */
if (!elems.fils_key_confirm) {
@@ -4430,9 +4480,11 @@
wpa_printf(MSG_DEBUG, "FILS: Auth+Assoc completed successfully");
sm->fils_completed = 1;
+ forced_memzero(&gd, sizeof(gd));
return 0;
fail:
+ forced_memzero(&gd, sizeof(gd));
return -1;
}
@@ -4644,7 +4696,7 @@
else if (group == 21)
res = hmac_sha512_kdf(prk, hash_len, NULL, (const u8 *) info,
os_strlen(info), sm->pmk, hash_len);
- os_memset(prk, 0, SHA512_MAC_LEN);
+ forced_memzero(prk, SHA512_MAC_LEN);
if (res < 0) {
sm->pmk_len = 0;
return -1;
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 8903f8e..ae9cd64 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -26,7 +26,7 @@
void (*set_state)(void *ctx, enum wpa_states state);
enum wpa_states (*get_state)(void *ctx);
- void (*deauthenticate)(void * ctx, int reason_code);
+ void (*deauthenticate)(void * ctx, u16 reason_code);
int (*set_key)(void *ctx, enum wpa_alg alg,
const u8 *addr, int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index 7dcb104..46ffdca 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -18,6 +18,7 @@
#include "drivers/driver.h"
#include "wpa.h"
#include "wpa_i.h"
+#include "pmksa_cache.h"
#ifdef CONFIG_IEEE80211R
@@ -27,15 +28,23 @@
u8 ptk_name[WPA_PMK_NAME_LEN];
const u8 *anonce = key->key_nonce;
int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
+ const u8 *mpmk;
+ size_t mpmk_len;
- if (sm->xxkey_len == 0) {
+ if (sm->xxkey_len > 0) {
+ mpmk = sm->xxkey;
+ mpmk_len = sm->xxkey_len;
+ } else if (sm->cur_pmksa) {
+ mpmk = sm->cur_pmksa->pmk;
+ mpmk_len = sm->cur_pmksa->pmk_len;
+ } else {
wpa_printf(MSG_DEBUG, "FT: XXKey not available for key "
"derivation");
return -1;
}
sm->pmk_r0_len = use_sha384 ? SHA384_MAC_LEN : PMK_LEN;
- if (wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, sm->ssid,
+ if (wpa_derive_pmk_r0(mpmk, mpmk_len, sm->ssid,
sm->ssid_len, sm->mobility_domain,
sm->r0kh_id, sm->r0kh_id_len, sm->own_addr,
sm->pmk_r0, sm->pmk_r0_name, use_sha384) < 0)
@@ -819,10 +828,10 @@
igtk_elem + 2, 6, igtk, igtk_len) < 0) {
wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the "
"driver.");
- os_memset(igtk, 0, sizeof(igtk));
+ forced_memzero(igtk, sizeof(igtk));
return -1;
}
- os_memset(igtk, 0, sizeof(igtk));
+ forced_memzero(igtk, sizeof(igtk));
return 0;
}
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 5dc9f2e..d86734b 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -126,8 +126,9 @@
u8 r0kh_id[FT_R0KH_ID_MAX_LEN];
size_t r0kh_id_len;
u8 r1kh_id[FT_R1KH_ID_LEN];
- int ft_completed;
- int ft_reassoc_completed;
+ unsigned int ft_completed:1;
+ unsigned int ft_reassoc_completed:1;
+ unsigned int ft_protocol:1;
int over_the_ds_in_progress;
u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */
int set_ptk_after_assoc;
@@ -187,7 +188,7 @@
return sm->ctx->get_state(sm->ctx->ctx);
}
-static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, int reason_code)
+static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, u16 reason_code)
{
WPA_ASSERT(sm->ctx->deauthenticate);
sm->ctx->deauthenticate(sm->ctx->ctx, reason_code);