Authenticator side testing functionality for EAPOL-Key Key Data field
Allow additional elements and KDEs to be added to EAPOL-Key msg 1/4 and 3/4 and allow EAPOL-Key msg 3/4 Key Data field to be not encrypted. These are for testing purposes to enable a convenient mechanism for testing supplicant behavior with either potential future extensions or incorrect Authenticator behavior. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
2a61071182
commit
3547ed403d
6 changed files with 78 additions and 1 deletions
|
@ -4355,6 +4355,14 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
bss->eap_skip_prot_success = atoi(pos);
|
bss->eap_skip_prot_success = atoi(pos);
|
||||||
} else if (os_strcmp(buf, "delay_eapol_tx") == 0) {
|
} else if (os_strcmp(buf, "delay_eapol_tx") == 0) {
|
||||||
conf->delay_eapol_tx = atoi(pos);
|
conf->delay_eapol_tx = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "eapol_m1_elements") == 0) {
|
||||||
|
if (parse_wpabuf_hex(line, buf, &bss->eapol_m1_elements, pos))
|
||||||
|
return 1;
|
||||||
|
} else if (os_strcmp(buf, "eapol_m3_elements") == 0) {
|
||||||
|
if (parse_wpabuf_hex(line, buf, &bss->eapol_m3_elements, pos))
|
||||||
|
return 1;
|
||||||
|
} else if (os_strcmp(buf, "eapol_m3_no_encrypt") == 0) {
|
||||||
|
bss->eapol_m3_no_encrypt = atoi(pos);
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
} else if (os_strcmp(buf, "sae_password") == 0) {
|
} else if (os_strcmp(buf, "sae_password") == 0) {
|
||||||
|
|
|
@ -948,6 +948,8 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
|
||||||
wpabuf_free(conf->rsnxe_override_ft);
|
wpabuf_free(conf->rsnxe_override_ft);
|
||||||
wpabuf_free(conf->gtk_rsc_override);
|
wpabuf_free(conf->gtk_rsc_override);
|
||||||
wpabuf_free(conf->igtk_rsc_override);
|
wpabuf_free(conf->igtk_rsc_override);
|
||||||
|
wpabuf_free(conf->eapol_m1_elements);
|
||||||
|
wpabuf_free(conf->eapol_m3_elements);
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
os_free(conf->no_probe_resp_if_seen_on);
|
os_free(conf->no_probe_resp_if_seen_on);
|
||||||
|
|
|
@ -704,6 +704,9 @@ struct hostapd_bss_config {
|
||||||
unsigned int oci_freq_override_ft_assoc;
|
unsigned int oci_freq_override_ft_assoc;
|
||||||
unsigned int oci_freq_override_fils_assoc;
|
unsigned int oci_freq_override_fils_assoc;
|
||||||
unsigned int oci_freq_override_wnm_sleep;
|
unsigned int oci_freq_override_wnm_sleep;
|
||||||
|
struct wpabuf *eapol_m1_elements;
|
||||||
|
struct wpabuf *eapol_m3_elements;
|
||||||
|
bool eapol_m3_no_encrypt;
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211BE
|
#ifdef CONFIG_IEEE80211BE
|
||||||
u16 eht_oper_puncturing_override;
|
u16 eht_oper_puncturing_override;
|
||||||
|
|
|
@ -623,6 +623,17 @@ int wpa_init_keys(struct wpa_authenticator *wpa_auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpa_auth_free_conf(struct wpa_auth_config *conf)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
wpabuf_free(conf->eapol_m1_elements);
|
||||||
|
conf->eapol_m1_elements = NULL;
|
||||||
|
wpabuf_free(conf->eapol_m3_elements);
|
||||||
|
conf->eapol_m3_elements = NULL;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wpa_deinit - Deinitialize WPA authenticator
|
* wpa_deinit - Deinitialize WPA authenticator
|
||||||
* @wpa_auth: Pointer to WPA authenticator data from wpa_init()
|
* @wpa_auth: Pointer to WPA authenticator data from wpa_init()
|
||||||
|
@ -656,6 +667,7 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth)
|
||||||
bin_clear_free(prev, sizeof(*prev));
|
bin_clear_free(prev, sizeof(*prev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_auth_free_conf(&wpa_auth->conf);
|
||||||
os_free(wpa_auth);
|
os_free(wpa_auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,6 +685,7 @@ int wpa_reconfig(struct wpa_authenticator *wpa_auth,
|
||||||
if (!wpa_auth)
|
if (!wpa_auth)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
wpa_auth_free_conf(&wpa_auth->conf);
|
||||||
os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
|
os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
|
||||||
if (wpa_auth_gen_wpa_ie(wpa_auth)) {
|
if (wpa_auth_gen_wpa_ie(wpa_auth)) {
|
||||||
wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
|
wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
|
||||||
|
@ -2332,10 +2345,14 @@ SM_STATE(WPA_PTK, INITPSK)
|
||||||
|
|
||||||
SM_STATE(WPA_PTK, PTKSTART)
|
SM_STATE(WPA_PTK, PTKSTART)
|
||||||
{
|
{
|
||||||
u8 buf[2 * (2 + RSN_SELECTOR_LEN) + PMKID_LEN + ETH_ALEN];
|
u8 *buf;
|
||||||
|
size_t buf_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
|
||||||
u8 *pmkid = NULL;
|
u8 *pmkid = NULL;
|
||||||
size_t kde_len = 0;
|
size_t kde_len = 0;
|
||||||
u16 key_info;
|
u16 key_info;
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
struct wpa_auth_config *conf = &sm->wpa_auth->conf;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk);
|
SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk);
|
||||||
sm->PTKRequest = false;
|
sm->PTKRequest = false;
|
||||||
|
@ -2350,6 +2367,19 @@ SM_STATE(WPA_PTK, PTKSTART)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
if (sm->mld_assoc_link_id >= 0)
|
||||||
|
buf_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (conf->eapol_m1_elements)
|
||||||
|
buf_len += wpabuf_len(conf->eapol_m1_elements);
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
|
buf = os_zalloc(buf_len);
|
||||||
|
if (!buf)
|
||||||
|
return;
|
||||||
|
|
||||||
wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm), LOGGER_DEBUG,
|
wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm), LOGGER_DEBUG,
|
||||||
"sending 1/4 msg of 4-Way Handshake");
|
"sending 1/4 msg of 4-Way Handshake");
|
||||||
/*
|
/*
|
||||||
|
@ -2453,11 +2483,20 @@ SM_STATE(WPA_PTK, PTKSTART)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211BE */
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (conf->eapol_m1_elements) {
|
||||||
|
os_memcpy(buf + kde_len, wpabuf_head(conf->eapol_m1_elements),
|
||||||
|
wpabuf_len(conf->eapol_m1_elements));
|
||||||
|
kde_len += wpabuf_len(conf->eapol_m1_elements);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
key_info = WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE;
|
key_info = WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE;
|
||||||
if (sm->pairwise_set && sm->wpa != WPA_VERSION_WPA)
|
if (sm->pairwise_set && sm->wpa != WPA_VERSION_WPA)
|
||||||
key_info |= WPA_KEY_INFO_SECURE;
|
key_info |= WPA_KEY_INFO_SECURE;
|
||||||
wpa_send_eapol(sm->wpa_auth, sm, key_info, NULL,
|
wpa_send_eapol(sm->wpa_auth, sm, key_info, NULL,
|
||||||
sm->ANonce, kde_len ? buf : NULL, kde_len, 0, 0);
|
sm->ANonce, kde_len ? buf : NULL, kde_len, 0, 0);
|
||||||
|
os_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4260,6 +4299,11 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
|
||||||
|
|
||||||
kde_len += wpa_auth_ml_kdes_len(sm);
|
kde_len += wpa_auth_ml_kdes_len(sm);
|
||||||
|
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (conf->eapol_m3_elements)
|
||||||
|
kde_len += wpabuf_len(conf->eapol_m3_elements);
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
kde = os_malloc(kde_len);
|
kde = os_malloc(kde_len);
|
||||||
if (!kde)
|
if (!kde)
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -4374,6 +4418,17 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
|
||||||
|
|
||||||
pos = wpa_auth_ml_kdes(sm, pos);
|
pos = wpa_auth_ml_kdes(sm, pos);
|
||||||
|
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
if (conf->eapol_m3_elements) {
|
||||||
|
os_memcpy(pos, wpabuf_head(conf->eapol_m3_elements),
|
||||||
|
wpabuf_len(conf->eapol_m3_elements));
|
||||||
|
pos += wpabuf_len(conf->eapol_m3_elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conf->eapol_m3_no_encrypt)
|
||||||
|
encr = 0;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
wpa_send_eapol(sm->wpa_auth, sm,
|
wpa_send_eapol(sm->wpa_auth, sm,
|
||||||
(secure ? WPA_KEY_INFO_SECURE : 0) |
|
(secure ? WPA_KEY_INFO_SECURE : 0) |
|
||||||
(wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?
|
(wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?
|
||||||
|
|
|
@ -242,6 +242,9 @@ struct wpa_auth_config {
|
||||||
unsigned int igtk_rsc_override_set:1;
|
unsigned int igtk_rsc_override_set:1;
|
||||||
int ft_rsnxe_used;
|
int ft_rsnxe_used;
|
||||||
bool delay_eapol_tx;
|
bool delay_eapol_tx;
|
||||||
|
struct wpabuf *eapol_m1_elements;
|
||||||
|
struct wpabuf *eapol_m3_elements;
|
||||||
|
bool eapol_m3_no_encrypt;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
unsigned int oci_freq_override_eapol_m3;
|
unsigned int oci_freq_override_eapol_m3;
|
||||||
unsigned int oci_freq_override_eapol_g1;
|
unsigned int oci_freq_override_eapol_g1;
|
||||||
|
|
|
@ -183,6 +183,12 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
|
||||||
wconf->oci_freq_override_ft_assoc = conf->oci_freq_override_ft_assoc;
|
wconf->oci_freq_override_ft_assoc = conf->oci_freq_override_ft_assoc;
|
||||||
wconf->oci_freq_override_fils_assoc =
|
wconf->oci_freq_override_fils_assoc =
|
||||||
conf->oci_freq_override_fils_assoc;
|
conf->oci_freq_override_fils_assoc;
|
||||||
|
|
||||||
|
if (conf->eapol_m1_elements)
|
||||||
|
wconf->eapol_m1_elements = wpabuf_dup(conf->eapol_m1_elements);
|
||||||
|
if (conf->eapol_m3_elements)
|
||||||
|
wconf->eapol_m3_elements = wpabuf_dup(conf->eapol_m3_elements);
|
||||||
|
wconf->eapol_m3_no_encrypt = conf->eapol_m3_no_encrypt;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);
|
os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);
|
||||||
|
|
Loading…
Reference in a new issue