]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Authenticator side testing functionality for EAPOL-Key Key Data field
authorJouni Malinen <quic_jouni@quicinc.com>
Tue, 16 Jan 2024 11:04:59 +0000 (13:04 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 16 Jan 2024 11:04:59 +0000 (13:04 +0200)
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>
hostapd/config_file.c
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c

index 15aaca9240d998fda6726c7c7b9bf1bf48982d7b..0c0137b4f83c7e4912efeb9aa9e19693d869e527 100644 (file)
@@ -4355,6 +4355,14 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->eap_skip_prot_success = atoi(pos);
        } else if (os_strcmp(buf, "delay_eapol_tx") == 0) {
                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 */
 #ifdef CONFIG_SAE
        } else if (os_strcmp(buf, "sae_password") == 0) {
index 040f39e7fa081c76ae4448346ed0666df2f28531..42987918927fa1e1b94def2efb70c13eba276538 100644 (file)
@@ -948,6 +948,8 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
        wpabuf_free(conf->rsnxe_override_ft);
        wpabuf_free(conf->gtk_rsc_override);
        wpabuf_free(conf->igtk_rsc_override);
+       wpabuf_free(conf->eapol_m1_elements);
+       wpabuf_free(conf->eapol_m3_elements);
 #endif /* CONFIG_TESTING_OPTIONS */
 
        os_free(conf->no_probe_resp_if_seen_on);
index 1d39495595bfe4c3f812e7a4e52f5a0ab06f64bc..7e7c340cde741bd26d4d55c693f159e9a6b97319 100644 (file)
@@ -704,6 +704,9 @@ struct hostapd_bss_config {
        unsigned int oci_freq_override_ft_assoc;
        unsigned int oci_freq_override_fils_assoc;
        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
        u16 eht_oper_puncturing_override;
index 74925a4fffa894f22713234ad9ffd961b10f23ff..1b2a89a8012e811d45ff0c093766d90b0bb0e495 100644 (file)
@@ -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_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));
        }
 
+       wpa_auth_free_conf(&wpa_auth->conf);
        os_free(wpa_auth);
 }
 
@@ -673,6 +685,7 @@ int wpa_reconfig(struct wpa_authenticator *wpa_auth,
        if (!wpa_auth)
                return 0;
 
+       wpa_auth_free_conf(&wpa_auth->conf);
        os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
        if (wpa_auth_gen_wpa_ie(wpa_auth)) {
                wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
@@ -2332,10 +2345,14 @@ SM_STATE(WPA_PTK, INITPSK)
 
 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;
        size_t kde_len = 0;
        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->PTKRequest = false;
@@ -2350,6 +2367,19 @@ SM_STATE(WPA_PTK, PTKSTART)
                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,
                        "sending 1/4 msg of 4-Way Handshake");
        /*
@@ -2453,11 +2483,20 @@ SM_STATE(WPA_PTK, PTKSTART)
        }
 #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;
        if (sm->pairwise_set && sm->wpa != WPA_VERSION_WPA)
                key_info |= WPA_KEY_INFO_SECURE;
        wpa_send_eapol(sm->wpa_auth, sm, key_info, NULL,
                       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);
 
+#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);
        if (!kde)
                goto done;
@@ -4374,6 +4418,17 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
 
        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,
                       (secure ? WPA_KEY_INFO_SECURE : 0) |
                       (wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?
index 058d999025512c77c6b1612673019920c3ce7414..c74862307784c0238686d5fcb1ff656387d1c0df 100644 (file)
@@ -242,6 +242,9 @@ struct wpa_auth_config {
        unsigned int igtk_rsc_override_set:1;
        int ft_rsnxe_used;
        bool delay_eapol_tx;
+       struct wpabuf *eapol_m1_elements;
+       struct wpabuf *eapol_m3_elements;
+       bool eapol_m3_no_encrypt;
 #endif /* CONFIG_TESTING_OPTIONS */
        unsigned int oci_freq_override_eapol_m3;
        unsigned int oci_freq_override_eapol_g1;
index 76e8541566384435afd8c82603d0fc0136b8e112..5737ab8dced22884dc0d3c101ad6c4c7d4eb74b8 100644 (file)
@@ -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_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 */
 #ifdef CONFIG_P2P
        os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);