}
+#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)
{
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 &&
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);
+ }
+ 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");
+ }
}
- return wpa_auth_derive_ptk_ft(sm, ptk);
+#endif /* CONFIG_PASN */
+ return ret;
}
#endif /* CONFIG_IEEE80211R_AP */
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;
}
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;
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;
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];
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;
#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,
}
+#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)
{
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;
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;
#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;
#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;
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;
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;
}
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);
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;
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 */
};
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;
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;
}
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;
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);
#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
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) {