diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index a65a2964b..761abd7ce 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2110,10 +2110,8 @@ prepare_auth_resp_fils(struct hostapd_data *hapd, if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm))) { /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */ int res; - int use_sha384 = wpa_key_mgmt_sha384( - wpa_auth_sta_key_mgmt(sta->wpa_sm)); - res = wpa_auth_write_fte(hapd->wpa_auth, use_sha384, + res = wpa_auth_write_fte(hapd->wpa_auth, sta->wpa_sm, wpabuf_put(data, 0), wpabuf_tailroom(data)); if (res < 0) { diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 73feac429..060beaec6 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -3685,9 +3685,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) 2 + sm->assoc_resp_ftie[1]); res = 2 + sm->assoc_resp_ftie[1]; } else { - int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt); - - res = wpa_write_ftie(conf, use_sha384, + res = wpa_write_ftie(conf, sm->wpa_key_mgmt, + sm->xxkey_len, conf->r0_key_holder, conf->r0_key_holder_len, NULL, NULL, pos, @@ -5453,13 +5452,14 @@ wpa_auth_pmksa_get_fils_cache_id(struct wpa_authenticator *wpa_auth, #ifdef CONFIG_IEEE80211R_AP -int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384, +int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, u8 *buf, size_t len) { struct wpa_auth_config *conf = &wpa_auth->conf; - return wpa_write_ftie(conf, use_sha384, conf->r0_key_holder, - conf->r0_key_holder_len, + return wpa_write_ftie(conf, sm->wpa_key_mgmt, sm->xxkey_len, + conf->r0_key_holder, conf->r0_key_holder_len, NULL, NULL, buf, len, NULL, 0, 0); } #endif /* CONFIG_IEEE80211R_AP */ @@ -5673,9 +5673,8 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm, 2 + sm->assoc_resp_ftie[1]); res = 2 + sm->assoc_resp_ftie[1]; } else { - int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt); - - res = wpa_write_ftie(conf, use_sha384, + res = wpa_write_ftie(conf, sm->wpa_key_mgmt, + sm->xxkey_len, conf->r0_key_holder, conf->r0_key_holder_len, NULL, NULL, pos, diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index e8e6a8a6b..64e661640 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -535,7 +535,8 @@ int wpa_fils_validate_key_confirm(struct wpa_state_machine *sm, const u8 *ies, int get_sta_tx_parameters(struct wpa_state_machine *sm, int ap_max_chanwidth, int ap_seg1_idx, int *bandwidth, int *seg1_idx); -int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384, +int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, u8 *buf, size_t len); void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm, u8 *fils_anonce, u8 *fils_snonce, diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index b9f451d52..0e522180d 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -20,6 +20,7 @@ #include "crypto/aes_siv.h" #include "crypto/aes_wrap.h" #include "crypto/sha384.h" +#include "crypto/sha512.h" #include "crypto/random.h" #include "ap_config.h" #include "ieee802_11.h" @@ -805,15 +806,28 @@ int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len) } -int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384, +int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len, const u8 *r0kh_id, size_t r0kh_id_len, const u8 *anonce, const u8 *snonce, u8 *buf, size_t len, const u8 *subelem, size_t subelem_len, int rsnxe_used) { u8 *pos = buf, *ielen; - size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) : - sizeof(struct rsn_ftie); + size_t hdrlen; + + if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY && + key_len == SHA256_MAC_LEN) + hdrlen = sizeof(struct rsn_ftie); + else if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY && + key_len == SHA384_MAC_LEN) + hdrlen = sizeof(struct rsn_ftie_sha384); + else if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY && + key_len == SHA512_MAC_LEN) + hdrlen = sizeof(struct rsn_ftie_sha512); + else if (wpa_key_mgmt_sha384(key_mgmt)) + hdrlen = sizeof(struct rsn_ftie_sha384); + else + hdrlen = sizeof(struct rsn_ftie); if (len < 2 + hdrlen + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len + subelem_len) @@ -822,7 +836,20 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384, *pos++ = WLAN_EID_FAST_BSS_TRANSITION; ielen = pos++; - if (use_sha384) { + if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY && + key_len == SHA512_MAC_LEN) { + struct rsn_ftie_sha512 *hdr = (struct rsn_ftie_sha512 *) pos; + + os_memset(hdr, 0, sizeof(*hdr)); + pos += sizeof(*hdr); + WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used); + if (anonce) + os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN); + if (snonce) + os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN); + } else if ((key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY && + key_len == SHA384_MAC_LEN) || + wpa_key_mgmt_sha384(key_mgmt)) { struct rsn_ftie_sha384 *hdr = (struct rsn_ftie_sha384 *) pos; os_memset(hdr, 0, sizeof(*hdr)); @@ -2522,6 +2549,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, const u8 *kck; size_t kck_len; int use_sha384; + size_t key_len; if (sm == NULL) return pos; @@ -2705,7 +2733,20 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, rsnxe_used); } #endif /* CONFIG_TESTING_OPTIONS */ - res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len, + key_len = sm->xxkey_len; + if (!key_len) + key_len = sm->pmk_r1_len; + if (!key_len && sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY && + sm->wpa_auth->cb->get_psk) { + size_t psk_len; + + if (sm->wpa_auth->cb->get_psk(sm->wpa_auth->cb_ctx, + sm->addr, sm->p2p_dev_addr, + NULL, &psk_len, NULL)) + key_len = psk_len; + } + res = wpa_write_ftie(conf, sm->wpa_key_mgmt, key_len, + r0kh_id, r0kh_id_len, anonce, snonce, pos, end - pos, subelem, subelem_len, rsnxe_used); os_free(subelem); @@ -3282,7 +3323,8 @@ pmk_r1_derived: goto fail; pos += ret; - ret = wpa_write_ftie(conf, use_sha384, parse.r0kh_id, parse.r0kh_id_len, + ret = wpa_write_ftie(conf, parse.key_mgmt, pmk_r1_len, + parse.r0kh_id, parse.r0kh_id_len, sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0, 0); if (ret < 0) diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index 5bd699c25..99a95abfd 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -298,7 +298,7 @@ int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth, #ifdef CONFIG_IEEE80211R_AP int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len); -int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384, +int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len, const u8 *r0kh_id, size_t r0kh_id_len, const u8 *anonce, const u8 *snonce, u8 *buf, size_t len, const u8 *subelem, diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 71b423cbf..11faa9760 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -401,6 +401,14 @@ struct rsn_ftie_sha384 { /* followed by optional parameters */ } STRUCT_PACKED; +struct rsn_ftie_sha512 { + u8 mic_control[2]; + u8 mic[32]; + u8 anonce[WPA_NONCE_LEN]; + u8 snonce[WPA_NONCE_LEN]; + /* followed by optional parameters */ +} STRUCT_PACKED; + #define FTIE_SUBELEM_R1KH_ID 1 #define FTIE_SUBELEM_GTK 2 #define FTIE_SUBELEM_R0KH_ID 3