diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 53211f625..73feac429 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -149,6 +149,20 @@ static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth, } +#ifdef CONFIG_PASN +static inline int wpa_auth_set_ltf_keyseed(struct wpa_authenticator *wpa_auth, + const u8 *peer_addr, + const u8 *ltf_keyseed, + size_t ltf_keyseed_len) +{ + if (!wpa_auth->cb->set_ltf_keyseed) + return -1; + return wpa_auth->cb->set_ltf_keyseed(wpa_auth->cb_ctx, peer_addr, + ltf_keyseed, ltf_keyseed_len); +} +#endif /* CONFIG_PASN */ + + static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth, const u8 *addr, int idx, u8 *seq) { @@ -2311,6 +2325,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, const u8 *z = NULL; size_t z_len = 0, kdk_len; int akmp; + int ret; if (sm->wpa_auth->conf.force_kdk_derivation || (sm->wpa_auth->conf.secure_ltf && @@ -2324,16 +2339,33 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, if (sm->ft_completed) { u8 ptk_name[WPA_PMK_NAME_LEN]; - return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, - sm->SNonce, sm->ANonce, - sm->addr, sm->wpa_auth->addr, - sm->pmk_r1_name, - ptk, ptk_name, - sm->wpa_key_mgmt, - sm->pairwise, - kdk_len); + ret = wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, + sm->SNonce, sm->ANonce, + sm->addr, sm->wpa_auth->addr, + sm->pmk_r1_name, ptk, + ptk_name, sm->wpa_key_mgmt, + sm->pairwise, kdk_len); + } else { + ret = wpa_auth_derive_ptk_ft(sm, ptk); } - return wpa_auth_derive_ptk_ft(sm, ptk); + if (ret) { + wpa_printf(MSG_ERROR, "FT: PTK derivation failed"); + return ret; + } + +#ifdef CONFIG_PASN + if (sm->wpa_auth->conf.secure_ltf && + ieee802_11_rsnx_capab(sm->rsnxe, + WLAN_RSNX_CAPAB_SECURE_LTF)) { + ret = wpa_ltf_keyseed(ptk, sm->wpa_key_mgmt, + sm->pairwise); + if (ret) { + wpa_printf(MSG_ERROR, + "FT: LTF keyseed derivation failed"); + } + } +#endif /* CONFIG_PASN */ + return ret; } #endif /* CONFIG_IEEE80211R_AP */ @@ -2347,9 +2379,27 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, akmp = sm->wpa_key_mgmt; if (force_sha256) akmp |= WPA_KEY_MGMT_PSK_SHA256; - return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion", - sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce, - ptk, akmp, sm->pairwise, z, z_len, kdk_len); + ret = wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion", + sm->wpa_auth->addr, sm->addr, sm->ANonce, + snonce, ptk, akmp, sm->pairwise, z, z_len, + kdk_len); + if (ret) { + wpa_printf(MSG_DEBUG, + "WPA: PTK derivation failed"); + return ret; + } + +#ifdef CONFIG_PASN + if (sm->wpa_auth->conf.secure_ltf && + ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)) { + ret = wpa_ltf_keyseed(ptk, sm->wpa_key_mgmt, sm->pairwise); + if (ret) { + wpa_printf(MSG_DEBUG, + "WPA: LTF keyseed derivation failed"); + } + } +#endif /* CONFIG_PASN */ + return ret; } @@ -2380,6 +2430,19 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, fils_ft, &fils_ft_len, kdk_len); if (res < 0) return res; + +#ifdef CONFIG_PASN + if (sm->wpa_auth->conf.secure_ltf && + ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)) { + res = wpa_ltf_keyseed(&sm->PTK, sm->wpa_key_mgmt, sm->pairwise); + if (res) { + wpa_printf(MSG_ERROR, + "FILS: LTF keyseed derivation failed"); + return res; + } + } +#endif /* CONFIG_PASN */ + sm->PTK_valid = true; sm->tk_already_set = false; @@ -2883,6 +2946,19 @@ int fils_set_tk(struct wpa_state_machine *sm) wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver"); return -1; } + +#ifdef CONFIG_PASN + if (sm->wpa_auth->conf.secure_ltf && + ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF) && + wpa_auth_set_ltf_keyseed(sm->wpa_auth, sm->addr, + sm->PTK.ltf_keyseed, + sm->PTK.ltf_keyseed_len)) { + wpa_printf(MSG_ERROR, + "FILS: Failed to set LTF keyseed to driver"); + return -1; + } +#endif /* CONFIG_PASN */ + sm->pairwise_set = true; sm->tk_already_set = true; @@ -3481,6 +3557,21 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) return; } +#ifdef CONFIG_PASN + if (sm->wpa_auth->conf.secure_ltf && + ieee802_11_rsnx_capab(sm->rsnxe, + WLAN_RSNX_CAPAB_SECURE_LTF) && + wpa_auth_set_ltf_keyseed(sm->wpa_auth, sm->addr, + sm->PTK.ltf_keyseed, + sm->PTK.ltf_keyseed_len)) { + wpa_printf(MSG_ERROR, + "WPA: Failed to set LTF keyseed to driver"); + wpa_sta_disconnect(sm->wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); + return; + } +#endif /* CONFIG_PASN */ + /* WPA2 send GTK in the 4-way handshake */ secure = 1; gtk = gsm->GTK[gsm->GN - 1]; @@ -3692,6 +3783,22 @@ SM_STATE(WPA_PTK, PTKINITDONE) WLAN_REASON_PREV_AUTH_NOT_VALID); return; } + +#ifdef CONFIG_PASN + if (sm->wpa_auth->conf.secure_ltf && + ieee802_11_rsnx_capab(sm->rsnxe, + WLAN_RSNX_CAPAB_SECURE_LTF) && + wpa_auth_set_ltf_keyseed(sm->wpa_auth, sm->addr, + sm->PTK.ltf_keyseed, + sm->PTK.ltf_keyseed_len)) { + wpa_printf(MSG_ERROR, + "WPA: Failed to set LTF keyseed to driver"); + wpa_sta_disconnect(sm->wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); + return; + } +#endif /* CONFIG_PASN */ + /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ sm->pairwise_set = true; diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index c6ba422f7..e8e6a8a6b 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -350,6 +350,10 @@ struct wpa_auth_callbacks { #ifdef CONFIG_MESH int (*start_ampe)(void *ctx, const u8 *sta_addr); #endif /* CONFIG_MESH */ +#ifdef CONFIG_PASN + int (*set_ltf_keyseed)(void *ctx, const u8 *addr, const u8 *ltf_keyseed, + size_t ltf_keyseed_len); +#endif /* CONFIG_PASN */ }; struct wpa_authenticator * wpa_init(const u8 *addr, diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 7a9761359..1b1324b8d 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2805,6 +2805,20 @@ static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth, } +#ifdef CONFIG_PASN +static inline int wpa_auth_set_ltf_keyseed(struct wpa_authenticator *wpa_auth, + const u8 *peer_addr, + const u8 *ltf_keyseed, + size_t ltf_keyseed_len) +{ + if (!wpa_auth->cb->set_ltf_keyseed) + return -1; + return wpa_auth->cb->set_ltf_keyseed(wpa_auth->cb_ctx, peer_addr, + ltf_keyseed, ltf_keyseed_len); +} +#endif /* CONFIG_PASN */ + + static inline int wpa_auth_add_sta_ft(struct wpa_authenticator *wpa_auth, const u8 *addr) { @@ -2849,6 +2863,18 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm, int retry) sm->PTK.tk, klen, KEY_FLAG_PAIRWISE_RX_TX)) return; +#ifdef CONFIG_PASN + if (sm->wpa_auth->conf.secure_ltf && + ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF) && + wpa_auth_set_ltf_keyseed(sm->wpa_auth, sm->addr, + sm->PTK.ltf_keyseed, + sm->PTK.ltf_keyseed_len)) { + wpa_printf(MSG_ERROR, + "FT: Failed to set LTF keyseed to driver"); + return; + } +#endif /* CONFIG_PASN */ + /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ sm->pairwise_set = true; sm->tk_already_set = true; @@ -3210,6 +3236,15 @@ pmk_r1_derived: pairwise, kdk_len) < 0) return WLAN_STATUS_UNSPECIFIED_FAILURE; +#ifdef CONFIG_PASN + if (sm->wpa_auth->conf.secure_ltf && + ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF) && + wpa_ltf_keyseed(&sm->PTK, sm->wpa_key_mgmt, pairwise)) { + wpa_printf(MSG_DEBUG, "FT: Failed to derive LTF keyseed"); + return WLAN_STATUS_UNSPECIFIED_FAILURE; + } +#endif /* CONFIG_PASN */ + sm->pairwise = pairwise; sm->PTK_valid = true; sm->tk_already_set = false; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 1b4852cea..f388ffe9f 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -1470,6 +1470,21 @@ static void hostapd_request_radius_psk(void *ctx, const u8 *addr, int key_mgmt, #endif /* CONFIG_NO_RADIUS */ +#ifdef CONFIG_PASN +static int hostapd_set_ltf_keyseed(void *ctx, const u8 *peer_addr, + const u8 *ltf_keyseed, + size_t ltf_keyseed_len) +{ + struct hostapd_data *hapd = ctx; + + return hostapd_drv_set_secure_ranging_ctx(hapd, hapd->own_addr, + peer_addr, 0, 0, NULL, + ltf_keyseed_len, + ltf_keyseed, 0); +} +#endif /* CONFIG_PASN */ + + int hostapd_setup_wpa(struct hostapd_data *hapd) { struct wpa_auth_config _conf; @@ -1516,6 +1531,9 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) #ifndef CONFIG_NO_RADIUS .request_radius_psk = hostapd_request_radius_psk, #endif /* CONFIG_NO_RADIUS */ +#ifdef CONFIG_PASN + .set_ltf_keyseed = hostapd_set_ltf_keyseed, +#endif /* CONFIG_PASN */ }; const u8 *wpa_ie; size_t wpa_ie_len; diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 3e39947a5..af7955140 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -585,6 +585,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, struct wpa_ptk *ptk) { + int ret; const u8 *z = NULL; size_t z_len = 0, kdk_len; int akmp; @@ -618,11 +619,23 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, else kdk_len = 0; - return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", - sm->own_addr, sm->bssid, sm->snonce, - key->key_nonce, ptk, akmp, - sm->pairwise_cipher, z, z_len, - kdk_len); + ret = wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", + sm->own_addr, sm->bssid, sm->snonce, + key->key_nonce, ptk, akmp, + sm->pairwise_cipher, z, z_len, + kdk_len); + if (ret) { + wpa_printf(MSG_ERROR, "WPA: PTK derivation failed"); + return ret; + } + +#ifdef CONFIG_PASN + if (sm->secure_ltf && + ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)) + ret = wpa_ltf_keyseed(ptk, akmp, sm->pairwise_cipher); +#endif /* CONFIG_PASN */ + + return ret; } @@ -976,6 +989,20 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, return -1; } +#ifdef CONFIG_PASN + if (sm->secure_ltf && + ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF) && + wpa_sm_set_ltf_keyseed(sm, sm->own_addr, sm->bssid, + sm->ptk.ltf_keyseed_len, + sm->ptk.ltf_keyseed) < 0) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: Failed to set LTF keyseed to the driver (keylen=%zu bssid=" + MACSTR ")", sm->ptk.ltf_keyseed_len, + MAC2STR(sm->bssid)); + return -1; + } +#endif /* CONFIG_PASN */ + wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher, sm->dot11RSNAConfigPMKLifetime, &sm->ptk); @@ -4452,6 +4479,15 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, goto fail; } +#ifdef CONFIG_PASN + if (sm->secure_ltf && + ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF) && + wpa_ltf_keyseed(&sm->ptk, sm->key_mgmt, sm->pairwise_cipher)) { + wpa_printf(MSG_DEBUG, "FILS: Failed to derive LTF keyseed"); + goto fail; + } +#endif /* CONFIG_PASN */ + wpabuf_clear_free(dh_ss); dh_ss = NULL; diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index df32240c6..80262a23c 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -93,6 +93,11 @@ struct wpa_sm_ctx { void (*transition_disable)(void *ctx, u8 bitmap); void (*store_ptk)(void *ctx, u8 *addr, int cipher, u32 life_time, const struct wpa_ptk *ptk); +#ifdef CONFIG_PASN + int (*set_ltf_keyseed)(void *ctx, const u8 *own_addr, + const u8 *peer_addr, size_t ltf_keyseed_len, + const u8 *ltf_keyseed); +#endif /* CONFIG_PASN */ }; diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 9d4044c14..c681a99df 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -41,6 +41,7 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt); const u8 *mpmk; size_t mpmk_len, kdk_len; + int ret = 0; if (sm->xxkey_len > 0) { mpmk = sm->xxkey; @@ -75,10 +76,22 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, else kdk_len = 0; - return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce, - sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk, - ptk_name, sm->key_mgmt, sm->pairwise_cipher, - kdk_len); + ret = wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, + anonce, sm->own_addr, sm->bssid, + sm->pmk_r1_name, ptk, ptk_name, sm->key_mgmt, + sm->pairwise_cipher, kdk_len); + if (ret) { + wpa_printf(MSG_ERROR, "FT: PTK derivation failed"); + return ret; + } + +#ifdef CONFIG_PASN + if (sm->secure_ltf && + ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)) + ret = wpa_ltf_keyseed(ptk, sm->key_mgmt, sm->pairwise_cipher); +#endif /* CONFIG_PASN */ + + return ret; } @@ -688,6 +701,15 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, kdk_len) < 0) return -1; +#ifdef CONFIG_PASN + if (sm->secure_ltf && + ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF) && + wpa_ltf_keyseed(&sm->ptk, sm->key_mgmt, sm->pairwise_cipher)) { + wpa_printf(MSG_DEBUG, "FT: Failed to derive LTF keyseed"); + return -1; + } +#endif /* CONFIG_PASN */ + if (wpa_key_mgmt_fils(sm->key_mgmt)) { kck = sm->ptk.kck2; kck_len = sm->ptk.kck2_len; diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index fabd6cb26..3811c3bc4 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -483,6 +483,18 @@ static inline void wpa_sm_store_ptk(struct wpa_sm *sm, ptk); } +#ifdef CONFIG_PASN +static inline int wpa_sm_set_ltf_keyseed(struct wpa_sm *sm, const u8 *own_addr, + const u8 *peer_addr, + size_t ltf_keyseed_len, + const u8 *ltf_keyseed) +{ + WPA_ASSERT(sm->ctx->set_ltf_keyseed); + return sm->ctx->set_ltf_keyseed(sm->ctx->ctx, own_addr, peer_addr, + ltf_keyseed_len, ltf_keyseed); +} +#endif /* CONFIG_PASN */ + int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk, int ver, const u8 *dest, u16 proto, u8 *msg, size_t msg_len, u8 *key_mic); diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 35ca12308..c5cfa92e5 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -1385,6 +1385,21 @@ static void wpa_supplicant_store_ptk(void *ctx, u8 *addr, int cipher, #endif /* CONFIG_NO_WPA */ +#ifdef CONFIG_PASN +static int wpa_supplicant_set_ltf_keyseed(void *_wpa_s, const u8 *own_addr, + const u8 *peer_addr, + size_t ltf_keyseed_len, + const u8 *ltf_keyseed) +{ + struct wpa_supplicant *wpa_s = _wpa_s; + + return wpa_drv_set_secure_ranging_ctx(wpa_s, own_addr, peer_addr, 0, 0, + NULL, ltf_keyseed_len, + ltf_keyseed, 0); +} +#endif /* CONFIG_PASN */ + + int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) { #ifndef CONFIG_NO_WPA @@ -1447,6 +1462,9 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) ctx->channel_info = wpa_supplicant_channel_info; ctx->transition_disable = wpa_supplicant_transition_disable; ctx->store_ptk = wpa_supplicant_store_ptk; +#ifdef CONFIG_PASN + ctx->set_ltf_keyseed = wpa_supplicant_set_ltf_keyseed; +#endif /* CONFIG_PASN */ wpa_s->wpa = wpa_sm_init(ctx); if (wpa_s->wpa == NULL) {