diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 74c552756..7e3f9c83e 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2092,7 +2092,7 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr, snonce, anonce, &sm->PTK, ick, &ick_len, - sm->wpa_key_mgmt, sm->pairwise); + sm->wpa_key_mgmt, sm->pairwise, NULL, NULL); if (res < 0) return res; sm->PTK_valid = TRUE; diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index c82f3486b..8eabf5435 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -339,10 +339,12 @@ int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len, int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa, const u8 *snonce, const u8 *anonce, struct wpa_ptk *ptk, - u8 *ick, size_t *ick_len, int akmp, int cipher) + u8 *ick, size_t *ick_len, int akmp, int cipher, + u8 *fils_ft, size_t *fils_ft_len) { u8 data[2 * ETH_ALEN + 2 * FILS_NONCE_LEN]; - u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN]; + u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN + + FILS_FT_MAX_LEN]; size_t key_data_len; const char *label = "FILS PTK Derivation"; @@ -372,6 +374,18 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa, return -1; key_data_len = *ick_len + ptk->kek_len + ptk->tk_len; + if (fils_ft && fils_ft_len) { + if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) { + *fils_ft_len = 32; + } else if (akmp == WPA_KEY_MGMT_FT_FILS_SHA384) { + *fils_ft_len = 48; + } else { + *fils_ft_len = 0; + fils_ft = NULL; + } + key_data_len += *fils_ft_len; + } + if (wpa_key_mgmt_sha384(akmp)) { wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA384)"); if (sha384_prf(pmk, pmk_len, label, data, sizeof(data), @@ -400,7 +414,12 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa, os_memcpy(ptk->tk, tmp + *ick_len + ptk->kek_len, ptk->tk_len); wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len); - /* TODO: FILS-FT */ + if (fils_ft && fils_ft_len) { + os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len, + *fils_ft_len); + wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT", + fils_ft, *fils_ft_len); + } os_memset(tmp, 0, sizeof(tmp)); return 0; diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 6303510fe..c0773e8b2 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -202,6 +202,7 @@ struct wpa_eapol_key { #define WPA_KEK_MAX_LEN 64 #define WPA_TK_MAX_LEN 32 #define FILS_ICK_MAX_LEN 48 +#define FILS_FT_MAX_LEN 48 /** * struct wpa_ptk - WPA Pairwise Transient Key @@ -346,7 +347,8 @@ int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len, u8 *pmkid); int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa, const u8 *snonce, const u8 *anonce, struct wpa_ptk *ptk, - u8 *ick, size_t *ick_len, int akmp, int cipher); + u8 *ick, size_t *ick_len, int akmp, int cipher, + u8 *fils_ft, size_t *fils_ft_len); int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce, const u8 *anonce, const u8 *sta_addr, const u8 *bssid, const u8 *g_sta, size_t g_sta_len, diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 316d69254..79504de7a 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -3603,8 +3603,8 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid, sm->fils_nonce, sm->fils_anonce, &sm->ptk, - ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher) < - 0) { + ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher, + NULL, NULL) < 0) { wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK"); goto fail; }