]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PASN: Configure secure ranging context to the driver in AP mode
authorVinay Gannevaram <quic_vganneva@quicinc.com>
Thu, 7 Jul 2022 20:14:54 +0000 (01:44 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 2 Sep 2022 13:25:20 +0000 (16:25 +0300)
AP as a responder, on successful completion of PASN authentication
configures the required keys by using the command
QCA_NL80211_VENDOR_SUBCMD_SECURE_RANGING_CONTEXT to the driver.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/ap/ap_drv_ops.c
src/ap/ap_drv_ops.h
src/ap/ieee802_11.c
src/ap/sta_info.h

index 87c3b9006191f59742c070e078abec906f9e4efa..2155b8f7287947974318ed9c9f4d22d8bdbcea86 100644 (file)
@@ -1016,3 +1016,30 @@ int hostapd_drv_dpp_listen(struct hostapd_data *hapd, bool enable)
                return 0;
        return hapd->driver->dpp_listen(hapd->drv_priv, enable);
 }
+
+
+#ifdef CONFIG_PASN
+int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
+                                      const u8 *own_addr, const u8 *peer_addr,
+                                      u32 cipher, u8 tk_len, const u8 *tk,
+                                      u8 ltf_keyseed_len,
+                                      const u8 *ltf_keyseed, u32 action)
+{
+       struct secure_ranging_params params;
+
+       if (!hapd->driver || !hapd->driver->set_secure_ranging_ctx)
+               return 0;
+
+       os_memset(&params, 0, sizeof(params));
+       params.own_addr = own_addr;
+       params.peer_addr = peer_addr;
+       params.cipher = cipher;
+       params.tk_len = tk_len;
+       params.tk = tk;
+       params.ltf_keyseed_len = ltf_keyseed_len;
+       params.ltf_keyseed = ltf_keyseed;
+       params.action = action;
+
+       return hapd->driver->set_secure_ranging_ctx(hapd->drv_priv, &params);
+}
+#endif /* CONFIG_PASN */
index b4fb766ee8ffad5e6b9a0ad04af57223e1ed8cc2..93b2244990ce8567ca17232aa114939eaf83f9f3 100644 (file)
@@ -138,6 +138,11 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd);
 int hostapd_drv_update_dh_ie(struct hostapd_data *hapd, const u8 *peer,
                             u16 reason_code, const u8 *ie, size_t ielen);
 int hostapd_drv_dpp_listen(struct hostapd_data *hapd, bool enable);
+int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
+                                      const u8 *own_addr, const u8 *addr,
+                                      u32 cipher, u8 key_len, const u8 *key,
+                                      u8 ltf_keyseed_len,
+                                      const u8 *ltf_keyseed, u32 action);
 
 
 #include "drivers/driver.h"
index c43f18b4a59c5dabd5cc3a31e917c6ca0372a753..86761a26644c129cce591570b85d25742780ceee 100644 (file)
@@ -2667,6 +2667,15 @@ static void pasn_fils_auth_resp(struct hostapd_data *hapd,
                goto fail;
        }
 
+       if (pasn->secure_ltf) {
+               ret = wpa_ltf_keyseed(&pasn->ptk, pasn->akmp, pasn->cipher);
+               if (ret) {
+                       wpa_printf(MSG_DEBUG,
+                                  "PASN: FILS: Failed to derive LTF keyseed");
+                       goto fail;
+               }
+       }
+
        wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
 
        wpabuf_free(pasn->secret);
@@ -2848,6 +2857,38 @@ static struct wpabuf * pasn_get_wrapped_data(struct hostapd_data *hapd,
 }
 
 
+static int pasn_set_keys_from_cache(struct hostapd_data *hapd,
+                                   const u8 *own_addr, const u8 *sta_addr,
+                                   int cipher, int akmp)
+{
+       struct ptksa_cache_entry *entry;
+
+       entry = ptksa_cache_get(hapd->ptksa, sta_addr, cipher);
+       if (!entry) {
+               wpa_printf(MSG_DEBUG, "PASN: peer " MACSTR
+                          " not present in PTKSA cache", MAC2STR(sta_addr));
+               return -1;
+       }
+
+       if (os_memcmp(entry->own_addr, own_addr, ETH_ALEN) != 0) {
+               wpa_printf(MSG_DEBUG,
+                          "PASN: own addr " MACSTR " and PTKSA entry own addr "
+                          MACSTR " differ",
+                          MAC2STR(own_addr), MAC2STR(entry->own_addr));
+               return -1;
+       }
+
+       wpa_printf(MSG_DEBUG, "PASN: " MACSTR " present in PTKSA cache",
+                  MAC2STR(sta_addr));
+       hostapd_drv_set_secure_ranging_ctx(hapd, own_addr, sta_addr, cipher,
+                                          entry->ptk.tk_len, entry->ptk.tk,
+                                          entry->ptk.ltf_keyseed_len,
+                                          entry->ptk.ltf_keyseed, 0);
+
+       return 0;
+}
+
+
 static int
 pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta,
                 const u8 *cached_pmk, size_t cached_pmk_len,
@@ -2904,6 +2945,16 @@ pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta,
                return -1;
        }
 
+       if (sta->pasn->secure_ltf) {
+               ret = wpa_ltf_keyseed(&sta->pasn->ptk, sta->pasn->akmp,
+                                     sta->pasn->cipher);
+               if (ret) {
+                       wpa_printf(MSG_DEBUG,
+                                  "PASN: Failed to derive LTF keyseed");
+                       return -1;
+               }
+       }
+
        wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
        return 0;
 }
@@ -3180,6 +3231,13 @@ static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta,
                sta->pasn->kdk_len = 0;
        wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", sta->pasn->kdk_len);
 
+       if ((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_AP) &&
+           ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
+                                     WLAN_RSNX_CAPAB_SECURE_LTF))
+               sta->pasn->secure_ltf = true;
+       else
+               sta->pasn->secure_ltf = false;
+
        if (!elems.pasn_params || !elems.pasn_params_len) {
                wpa_printf(MSG_DEBUG,
                           "PASN: No PASN Parameters element found");
@@ -3504,6 +3562,8 @@ static void handle_auth_pasn_3(struct hostapd_data *hapd, struct sta_info *sta,
 
        ptksa_cache_add(hapd->ptksa, hapd->own_addr, sta->addr,
                        sta->pasn->cipher, 43200, &sta->pasn->ptk, NULL, NULL);
+       pasn_set_keys_from_cache(hapd, hapd->own_addr, sta->addr,
+                                sta->pasn->cipher, sta->pasn->akmp);
 fail:
        ap_free_sta(hapd, sta);
 }
index 5c92e01da491a87afe46908157fe8b266797e68e..d2a8344ad0d28325d1efacbac642adfc6306b5f4 100644 (file)
@@ -88,6 +88,7 @@ struct pasn_data {
        int akmp;
        int cipher;
        u16 group;
+       bool secure_ltf;
        u8 trans_seq;
        u8 wrapped_data_format;
        size_t kdk_len;