Allow RSNE/RSNXE to be replaced in FT protocol Reassocation Response frame

This can be used to test station side behavior for FT protocol
validation steps.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2020-03-14 23:30:27 +02:00
parent 1a8e9334c0
commit 46e147fcdc
7 changed files with 86 additions and 2 deletions

View file

@ -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);

View file

@ -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 */

View file

@ -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 */

View file

@ -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) &&

View file

@ -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 */

View file

@ -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;

View file

@ -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) {