diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 98e9fd21b..1a5b742b2 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -4182,6 +4182,12 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "rsnxe_override_eapol") == 0) { wpabuf_free(bss->rsnxe_override_eapol); bss->rsnxe_override_eapol = wpabuf_parse_bin(pos); + } else if (os_strcmp(buf, "rsne_override_ft") == 0) { + wpabuf_free(bss->rsne_override_ft); + bss->rsne_override_ft = wpabuf_parse_bin(pos); + } else if (os_strcmp(buf, "rsnxe_override_ft") == 0) { + wpabuf_free(bss->rsnxe_override_ft); + bss->rsnxe_override_ft = wpabuf_parse_bin(pos); } else if (os_strcmp(buf, "gtk_rsc_override") == 0) { wpabuf_free(bss->gtk_rsc_override); bss->gtk_rsc_override = wpabuf_parse_bin(pos); diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 0166c3164..5bf4502b0 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -904,6 +904,8 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) wpabuf_free(conf->sae_commit_override); wpabuf_free(conf->rsne_override_eapol); wpabuf_free(conf->rsnxe_override_eapol); + wpabuf_free(conf->rsne_override_ft); + wpabuf_free(conf->rsnxe_override_ft); wpabuf_free(conf->gtk_rsc_override); wpabuf_free(conf->igtk_rsc_override); #endif /* CONFIG_TESTING_OPTIONS */ diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 8b57500ce..0cb10c118 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -679,6 +679,8 @@ struct hostapd_bss_config { struct wpabuf *sae_commit_override; struct wpabuf *rsne_override_eapol; struct wpabuf *rsnxe_override_eapol; + struct wpabuf *rsne_override_ft; + struct wpabuf *rsnxe_override_ft; struct wpabuf *gtk_rsc_override; struct wpabuf *igtk_rsc_override; #endif /* CONFIG_TESTING_OPTIONS */ diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 7937b8120..46cc7fae7 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3810,7 +3810,22 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, } #endif /* CONFIG_FST */ +#ifdef CONFIG_TESTING_OPTIONS + if (hapd->conf->rsnxe_override_ft && + buf + buflen - p >= + (long int) wpabuf_len(hapd->conf->rsnxe_override_ft) && + sta && sta->auth_alg == WLAN_AUTH_FT) { + wpa_printf(MSG_DEBUG, "TESTING: RSNXE FT override"); + os_memcpy(p, wpabuf_head(hapd->conf->rsnxe_override_ft), + wpabuf_len(hapd->conf->rsnxe_override_ft)); + p += wpabuf_len(hapd->conf->rsnxe_override_ft); + goto rsnxe_done; + } +#endif /* CONFIG_TESTING_OPTIONS */ p = hostapd_eid_rsnxe(hapd, p, buf + buflen - p); +#ifdef CONFIG_TESTING_OPTIONS +rsnxe_done: +#endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_OWE if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) && diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index d1324d501..4edeea151 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -225,10 +225,16 @@ struct wpa_auth_config { size_t rsne_override_eapol_len; u8 rsnxe_override_eapol[MAX_OWN_IE_OVERRIDE]; size_t rsnxe_override_eapol_len; + u8 rsne_override_ft[MAX_OWN_IE_OVERRIDE]; + size_t rsne_override_ft_len; + u8 rsnxe_override_ft[MAX_OWN_IE_OVERRIDE]; + size_t rsnxe_override_ft_len; u8 gtk_rsc_override[WPA_KEY_RSC_LEN]; u8 igtk_rsc_override[WPA_KEY_RSC_LEN]; unsigned int rsne_override_eapol_set:1; unsigned int rsnxe_override_eapol_set:1; + unsigned int rsne_override_ft_set:1; + unsigned int rsnxe_override_ft_set:1; unsigned int gtk_rsc_override_set:1; unsigned int igtk_rsc_override_set:1; #endif /* CONFIG_TESTING_OPTIONS */ diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index c0b462558..1795848e1 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2468,7 +2468,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL; u8 *fte_mic, *elem_count; size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0; - u8 rsnxe[10]; + u8 rsnxe_buf[10], *rsnxe = rsnxe_buf; size_t rsnxe_len; int res; struct wpa_auth_config *conf; @@ -2490,6 +2490,32 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, end = pos + max_len; +#ifdef CONFIG_TESTING_OPTIONS + if (auth_alg == WLAN_AUTH_FT && + sm->wpa_auth->conf.rsne_override_ft_set) { + wpa_printf(MSG_DEBUG, + "TESTING: RSNE FT override for MIC calculation"); + rsnie = sm->wpa_auth->conf.rsne_override_ft; + rsnie_len = sm->wpa_auth->conf.rsne_override_ft_len; + if (end - pos < (long int) rsnie_len) + return pos; + os_memcpy(pos, rsnie, rsnie_len); + rsnie = pos; + pos += rsnie_len; + if (rsnie_len > PMKID_LEN && sm->pmk_r1_name_valid) { + int idx; + + /* Replace all 0xff PMKID with the valid PMKR1Name */ + for (idx = 0; idx < PMKID_LEN; idx++) { + if (rsnie[rsnie_len - 1 - idx] != 0xff) + break; + } + if (idx == PMKID_LEN) + os_memcpy(&rsnie[rsnie_len - PMKID_LEN], + sm->pmk_r1_name, WPA_PMK_NAME_LEN); + } + } else +#endif /* CONFIG_TESTING_OPTIONS */ if (auth_alg == WLAN_AUTH_FT || ((auth_alg == WLAN_AUTH_FILS_SK || auth_alg == WLAN_AUTH_FILS_SK_PFS || @@ -2655,10 +2681,19 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, if (ric_start == pos) ric_start = NULL; - res = wpa_write_rsnxe(&sm->wpa_auth->conf, rsnxe, sizeof(rsnxe)); + res = wpa_write_rsnxe(&sm->wpa_auth->conf, rsnxe, sizeof(rsnxe_buf)); if (res < 0) return NULL; rsnxe_len = res; +#ifdef CONFIG_TESTING_OPTIONS + if (auth_alg == WLAN_AUTH_FT && + sm->wpa_auth->conf.rsnxe_override_ft_set) { + wpa_printf(MSG_DEBUG, + "TESTING: RSNXE FT override for MIC calculation"); + rsnxe = sm->wpa_auth->conf.rsnxe_override_ft; + rsnxe_len = sm->wpa_auth->conf.rsnxe_override_ft_len; + } +#endif /* CONFIG_TESTING_OPTIONS */ if (auth_alg == WLAN_AUTH_FT && rsnxe_len) *elem_count += 1; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index ff2302cd2..926ff455f 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -139,6 +139,24 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, wpabuf_head(conf->rsnxe_override_eapol), wconf->rsnxe_override_eapol_len); } + if (conf->rsne_override_ft && + wpabuf_len(conf->rsne_override_ft) <= MAX_OWN_IE_OVERRIDE) { + wconf->rsne_override_ft_set = 1; + wconf->rsne_override_ft_len = + wpabuf_len(conf->rsne_override_ft); + os_memcpy(wconf->rsne_override_ft, + wpabuf_head(conf->rsne_override_ft), + wconf->rsne_override_ft_len); + } + if (conf->rsnxe_override_ft && + wpabuf_len(conf->rsnxe_override_ft) <= MAX_OWN_IE_OVERRIDE) { + wconf->rsnxe_override_ft_set = 1; + wconf->rsnxe_override_ft_len = + wpabuf_len(conf->rsnxe_override_ft); + os_memcpy(wconf->rsnxe_override_ft, + wpabuf_head(conf->rsnxe_override_ft), + wconf->rsnxe_override_ft_len); + } if (conf->gtk_rsc_override && wpabuf_len(conf->gtk_rsc_override) > 0 && wpabuf_len(conf->gtk_rsc_override) <= WPA_KEY_RSC_LEN) {