Skip SAE fixed auth body fields, so the parsing is done at correct offset. Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@xxxxxxxxx> --- src/ap/ieee802_11.c | 3 ++- src/common/common_module_tests.c | 2 +- src/common/sae.c | 5 ++++- src/common/sae.h | 2 +- src/pasn/pasn_initiator.c | 2 +- src/pasn/pasn_responder.c | 2 +- tests/fuzzing/sae/sae.c | 4 ++-- wpa_supplicant/sme.c | 32 +++++++++++++++++++++++--------- 8 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index ba3c6009e4..6b0dc0690b 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1348,7 +1348,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, mgmt->u.auth.variable, &token, &token_len, groups, status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT || - status_code == WLAN_STATUS_SAE_PK); + status_code == WLAN_STATUS_SAE_PK, + NULL); if (resp == SAE_SILENTLY_DISCARD) { wpa_printf(MSG_DEBUG, "SAE: Drop commit message from " MACSTR " due to reflection attack", diff --git a/src/common/common_module_tests.c b/src/common/common_module_tests.c index 8aba713f92..a95ae36dc0 100644 --- a/src/common/common_module_tests.c +++ b/src/common/common_module_tests.c @@ -428,7 +428,7 @@ static int sae_tests(void) } if (sae_parse_commit(&sae, peer_commit, sizeof(peer_commit), NULL, NULL, - NULL, 0) != 0 || + NULL, 0, NULL) != 0 || sae_process_commit(&sae) < 0) goto fail; diff --git a/src/common/sae.c b/src/common/sae.c index e597bfc1ac..0285f4db53 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -2155,7 +2155,7 @@ static int sae_parse_akm_suite_selector(struct sae_data *sae, u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len, const u8 **token, size_t *token_len, int *allowed_groups, - int h2e) + int h2e, int *ie_offset) { const u8 *pos = data, *end = data + len; u16 res; @@ -2181,6 +2181,9 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len, if (res != WLAN_STATUS_SUCCESS) return res; + if (ie_offset) + *ie_offset = pos - data; + /* Optional Password Identifier element */ res = sae_parse_password_identifier(sae, &pos, end); if (res != WLAN_STATUS_SUCCESS) diff --git a/src/common/sae.h b/src/common/sae.h index 6a6b0c8241..7b6a083f14 100644 --- a/src/common/sae.h +++ b/src/common/sae.h @@ -136,7 +136,7 @@ int sae_write_commit(struct sae_data *sae, struct wpabuf *buf, const struct wpabuf *token, const char *identifier); u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len, const u8 **token, size_t *token_len, int *allowed_groups, - int h2e); + int h2e, int *ie_offset); int sae_write_confirm(struct sae_data *sae, struct wpabuf *buf); int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len); u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group); diff --git a/src/pasn/pasn_initiator.c b/src/pasn/pasn_initiator.c index a98eba20cf..fd63d7d8f4 100644 --- a/src/pasn/pasn_initiator.c +++ b/src/pasn/pasn_initiator.c @@ -108,7 +108,7 @@ static int wpas_pasn_wd_sae_rx(struct pasn_data *pasn, struct wpabuf *wd) } res = sae_parse_commit(&pasn->sae, data + 6, len - 6, NULL, 0, groups, - 1); + 1, NULL); if (res != WLAN_STATUS_SUCCESS) { wpa_printf(MSG_DEBUG, "PASN: SAE failed parsing commit"); return -1; diff --git a/src/pasn/pasn_responder.c b/src/pasn/pasn_responder.c index ea2737c0f3..d066a0c62a 100644 --- a/src/pasn/pasn_responder.c +++ b/src/pasn/pasn_responder.c @@ -85,7 +85,7 @@ static int pasn_wd_handle_sae_commit(struct pasn_data *pasn, } res = sae_parse_commit(&pasn->sae, data + 6, buf_len - 6, NULL, 0, - groups, 0); + groups, 0, NULL); if (res != WLAN_STATUS_SUCCESS) { wpa_printf(MSG_DEBUG, "PASN: Failed parsing SAE commit"); return -1; diff --git a/tests/fuzzing/sae/sae.c b/tests/fuzzing/sae/sae.c index 8819a4abbc..74faeeda6f 100644 --- a/tests/fuzzing/sae/sae.c +++ b/tests/fuzzing/sae/sae.c @@ -27,10 +27,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) return 0; os_memset(&sae, 0, sizeof(sae)); - res = sae_parse_commit(&sae, data, size, &token, &token_len, groups, 0); + res = sae_parse_commit(&sae, data, size, &token, &token_len, groups, 0, NULL); wpa_printf(MSG_DEBUG, "sae_parse_commit(0): %u", res); sae_clear_data(&sae); - res = sae_parse_commit(&sae, data, size, &token, &token_len, groups, 1); + res = sae_parse_commit(&sae, data, size, &token, &token_len, groups, 1, NULL); wpa_printf(MSG_DEBUG, "sae_parse_commit(1): %u", res); sae_clear_data(&sae); os_program_deinit(); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index e7e7cada9d..f2bd64afc4 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -514,7 +514,8 @@ out: static void wpas_sme_ml_auth(struct wpa_supplicant *wpa_s, - union wpa_event_data *data) + union wpa_event_data *data, + int ie_offset) { struct ieee802_11_elems elems; const u8 *mld_addr; @@ -522,7 +523,8 @@ static void wpas_sme_ml_auth(struct wpa_supplicant *wpa_s, if (!wpa_s->mld) return; - if (ieee802_11_parse_elems(data->auth.ies, data->auth.ies_len, + if (ieee802_11_parse_elems(data->auth.ies + ie_offset, + data->auth.ies_len - ie_offset, &elems, 0) != ParseOK) { wpa_printf(MSG_DEBUG, "MLD: failed parsing elements"); goto out; @@ -1530,7 +1532,7 @@ static int sme_check_sae_rejected_groups(struct wpa_supplicant *wpa_s, static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, u16 status_code, const u8 *data, size_t len, - int external, const u8 *sa) + int external, const u8 *sa, int *ie_offset) { int *groups; @@ -1594,6 +1596,10 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, } token_len = elen - 1; } + + if (ie_offset) + *ie_offset = token_pos + token_len - data; + wpa_s->sme.sae_token = wpabuf_alloc_copy(token_pos, token_len); wpa_hexdump_buf(MSG_DEBUG, "SME: Requested anti-clogging token", wpa_s->sme.sae_token); @@ -1689,7 +1695,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL, groups, status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT || - status_code == WLAN_STATUS_SAE_PK); + status_code == WLAN_STATUS_SAE_PK, + ie_offset); if (res == SAE_SILENTLY_DISCARD) { wpa_printf(MSG_DEBUG, "SAE: Drop commit message due to reflection attack"); @@ -1726,6 +1733,10 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, return -1; if (sae_check_confirm(&wpa_s->sme.sae, data, len) < 0) return -1; + + if (ie_offset && wpa_s->sme.sae.tmp) + *ie_offset = 2 + wpa_s->sme.sae.tmp->kck_len; + wpa_s->sme.sae.state = SAE_ACCEPTED; sae_clear_temp_data(&wpa_s->sme.sae); @@ -1796,7 +1807,7 @@ void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s, wpa_s, le_to_host16(header->u.auth.auth_transaction), le_to_host16(header->u.auth.status_code), header->u.auth.variable, - len - auth_length, 1, header->sa); + len - auth_length, 1, header->sa, NULL); if (res < 0) { /* Notify failure to the driver */ sme_send_external_auth_status( @@ -1820,6 +1831,7 @@ void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s, void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { struct wpa_ssid *ssid = wpa_s->current_ssid; + int ie_offset = 0; if (ssid == NULL) { wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " @@ -1864,7 +1876,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) int res; res = sme_sae_auth(wpa_s, data->auth.auth_transaction, data->auth.status_code, data->auth.ies, - data->auth.ies_len, 0, data->auth.peer); + data->auth.ies_len, 0, data->auth.peer, + &ie_offset); if (res < 0) { wpas_connection_failed(wpa_s, wpa_s->pending_bssid); wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); @@ -2004,9 +2017,10 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) } #endif /* CONFIG_FILS */ - /* TODO: Support for other auth_type as well */ - if (data->auth.auth_type == WLAN_AUTH_OPEN) - wpas_sme_ml_auth(wpa_s, data); + /* TODO: Support additional auth_type's as well */ + if (data->auth.auth_type == WLAN_AUTH_OPEN || + data->auth.auth_type == WLAN_AUTH_SAE) + wpas_sme_ml_auth(wpa_s, data, ie_offset); sme_associate(wpa_s, ssid->mode, data->auth.peer, data->auth.auth_type); -- 2.25.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap