]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PR: Manage Device Identity Key, password, and PMK
authorPeddolla Harshavardhan Reddy <peddolla@qti.qualcomm.com>
Sat, 26 Apr 2025 19:25:54 +0000 (00:55 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 17 Oct 2025 10:22:51 +0000 (13:22 +0300)
Add functionality for adding and clearing the Device Identity Key (DIK),
password, and PMK. These are associated with the DIK and are stored in a
list that is linked to the global Proximity Ranging context.

Signed-off-by: Peddolla Harshavardhan Reddy <peddolla@qti.qualcomm.com>
src/common/proximity_ranging.c
src/common/proximity_ranging.h
wpa_supplicant/pr_supplicant.c
wpa_supplicant/pr_supplicant.h

index 341c0de7c7892aabe38d1e0e77fed768c927a8aa..41144cb28fb04a9cee80467a3286c599d520232f 100644 (file)
@@ -84,11 +84,24 @@ struct pr_data * pr_init(const struct pr_config *cfg)
                pr->cfg->dev_name = NULL;
 
        dl_list_init(&pr->devices);
+       dl_list_init(&pr->dev_iks);
 
        return pr;
 }
 
 
+static void pr_deinit_dev_iks(struct pr_data *pr)
+{
+       struct pr_dev_ik *dev_ik, *prev_dev_ik;
+
+       dl_list_for_each_safe(dev_ik, prev_dev_ik, &pr->dev_iks,
+                             struct pr_dev_ik, list) {
+               dl_list_del(&dev_ik->list);
+               os_free(dev_ik);
+       }
+}
+
+
 void pr_deinit(struct pr_data *pr)
 {
        struct pr_device *dev, *prev;
@@ -103,11 +116,76 @@ void pr_deinit(struct pr_data *pr)
                pr_device_free(pr, dev);
        }
 
+       pr_deinit_dev_iks(pr);
+
        os_free(pr);
        wpa_printf(MSG_DEBUG, "PR: Deinit done");
 }
 
 
+void pr_clear_dev_iks(struct pr_data *pr)
+{
+       struct pr_device *dev;
+
+       pr->cfg->dik_len = 0;
+       os_memset(pr->cfg->dik_data, 0, DEVICE_IDENTITY_KEY_LEN);
+       pr->cfg->global_password_valid = false;
+       os_memset(pr->cfg->global_password, 0,
+                 sizeof(pr->cfg->global_password));
+
+       dl_list_for_each(dev, &pr->devices, struct pr_device, list) {
+               dev->password_valid = false;
+               os_memset(dev->password, 0, sizeof(dev->password));
+       }
+
+       pr_deinit_dev_iks(pr);
+}
+
+
+void pr_add_dev_ik(struct pr_data *pr, const u8 *dik, const char *password,
+                  const u8 *pmk, bool own)
+{
+       struct pr_dev_ik *dev_ik;
+
+       if (own) {
+               os_memcpy(pr->cfg->dik_data, dik, DEVICE_IDENTITY_KEY_LEN);
+               pr->cfg->dik_len = DEVICE_IDENTITY_KEY_LEN;
+               if (password) {
+                       os_strlcpy(pr->cfg->global_password, password,
+                                  sizeof(pr->cfg->global_password));
+                       pr->cfg->global_password_valid = true;
+               }
+               return;
+       }
+
+       dl_list_for_each(dev_ik, &pr->dev_iks, struct pr_dev_ik, list) {
+               if (os_memcmp(dik, dev_ik->dik, DEVICE_IDENTITY_KEY_LEN) == 0) {
+                       dl_list_del(&dev_ik->list);
+                       os_free(dev_ik);
+                       break;
+               }
+       }
+
+       dev_ik = os_zalloc(sizeof(*dev_ik));
+       if (!dev_ik)
+               return;
+
+       dl_list_add(&pr->dev_iks, &dev_ik->list);
+       os_memcpy(dev_ik->dik, dik, DEVICE_IDENTITY_KEY_LEN);
+       if (password) {
+               os_strlcpy(dev_ik->password, password,
+                          sizeof(dev_ik->password));
+               dev_ik->password_valid = true;
+       }
+       if (pmk) {
+               os_memcpy(dev_ik->pmk, pmk, WPA_PASN_PMK_LEN);
+               dev_ik->pmk_valid = true;
+       }
+
+       wpa_printf(MSG_DEBUG, "PR: New Device Identity added to list");
+}
+
+
 static struct wpabuf * pr_encaps_elem(const struct wpabuf *subelems,
                                      u32 ie_type)
 {
index b05dc54c7e0626edcbed75fe6d863b6418fbfb88..6734e9c40a6b0cc705e39578ea7370f35698977e 100644 (file)
@@ -9,6 +9,7 @@
 #ifndef PROXIMITY_RANGING_H
 #define PROXIMITY_RANGING_H
 
+#include "wpa_common.h"
 #include "utils/list.h"
 #include "wps/wps_defs.h"
 
@@ -225,6 +226,15 @@ enum pr_attr_id {
 #define PR_ISTA_SUPPORT BIT(0)
 #define PR_RSTA_SUPPORT BIT(1)
 
+struct pr_dev_ik {
+       struct dl_list list;
+       u8 dik[DEVICE_IDENTITY_KEY_LEN];
+       char password[100];
+       bool password_valid;
+       u8 pmk[WPA_PASN_PMK_LEN];
+       bool pmk_valid;
+};
+
 /**
  * struct pr_device_info - Proximity ranging peer information
  */
@@ -237,6 +247,18 @@ struct pr_device {
         * pr_device_addr - PR Device Address of the peer
         */
        u8 pr_device_addr[ETH_ALEN];
+
+       /* Password to be used in PASN-SAE by the Seeker.
+        * This is updated with valid password if DIRA matches for the peer.
+        */
+       char password[100];
+       bool password_valid;
+
+       /* PMK to be used in PASN-PMK by the Seeker.
+        * This is updated with valid PMK if DIRA matches for the peer.
+        */
+       u8 pmk[PMK_LEN_MAX];
+       bool pmk_valid;
 };
 
 
@@ -306,6 +328,11 @@ struct pr_config {
        /* DevIK expiration */
        int expiration;
 
+       /* Global password to be used in PASN-SAE for Advertiser */
+       char global_password[100];
+
+       bool global_password_valid;
+
        /**
         * cb_ctx - Context to use with callback functions
         */
@@ -322,6 +349,8 @@ struct pr_data {
        struct pr_config *cfg;
 
        struct dl_list devices;
+
+       struct dl_list dev_iks;
 };
 
 /* PR Device Identity Resolution Attribute parameters */
@@ -340,6 +369,9 @@ struct pr_dira {
 
 struct pr_data * pr_init(const struct pr_config *cfg);
 void pr_deinit(struct pr_data *pr);
+void pr_clear_dev_iks(struct pr_data *pr);
+void pr_add_dev_ik(struct pr_data *pr, const u8 *dik, const char *password,
+                  const u8 *pmk, bool own);
 struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr);
 void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
                          const u8 *peer_addr, unsigned int freq);
index 961d5711ee30f58163b80a725068a1c6f8c539da..bf6905e50c92980f21cac3974698a6a726b4bf94 100644 (file)
@@ -361,3 +361,26 @@ void wpas_pr_deinit(struct wpa_supplicant *wpa_s)
                wpa_s->global->pr_init_wpa_s = NULL;
        }
 }
+
+
+void wpas_pr_clear_dev_iks(struct wpa_supplicant *wpa_s)
+{
+       struct pr_data *pr = wpa_s->global->pr;
+
+       if (!pr)
+               return;
+
+       pr_clear_dev_iks(pr);
+}
+
+
+void wpas_pr_set_dev_ik(struct wpa_supplicant *wpa_s, const u8 *dik,
+                       const char *password, const u8 *pmk, bool own)
+{
+       struct pr_data *pr = wpa_s->global->pr;
+
+       if (!pr || !dik)
+               return;
+
+       pr_add_dev_ik(pr, dik, password, pmk, own);
+}
index 6877fa84277e58dcf872f78d76b9b2c1eb3e57b1..931d307802a35616b7c63f898402a8e40450f69d 100644 (file)
@@ -14,6 +14,9 @@
 int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s,
                 const struct wpa_driver_capa *capa);
 void wpas_pr_deinit(struct wpa_supplicant *wpa_s);
+void wpas_pr_clear_dev_iks(struct wpa_supplicant *wpa_s);
+void wpas_pr_set_dev_ik(struct wpa_supplicant *wpa_s, const u8 *dik,
+                       const char *password, const u8 *pmk, bool own);
 struct wpabuf * wpas_pr_usd_elems(struct wpa_supplicant *wpa_s);
 void wpas_pr_process_usd_elems(struct wpa_supplicant *wpa_s, const u8 *buf,
                               u16 buf_len, const u8 *peer_addr,
@@ -32,6 +35,16 @@ static inline void wpas_pr_deinit(struct wpa_supplicant *wpa_s)
 {
 }
 
+static inline void wpas_pr_clear_dev_iks(struct wpa_supplicant *wpa_s)
+{
+}
+
+static inline void wpas_pr_set_dev_ik(struct wpa_supplicant *wpa_s,
+                                     const u8 *dik, const char *password,
+                                     const u8 *pmk, bool own)
+{
+}
+
 static inline struct wpabuf * wpas_pr_usd_elems(struct wpa_supplicant *wpa_s)
 {
        return NULL;