From: Peddolla Harshavardhan Reddy Date: Sat, 26 Apr 2025 19:25:54 +0000 (+0530) Subject: PR: Manage Device Identity Key, password, and PMK X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e05e8ae74ff884eb74301afc5acb63ff3ec1a06;p=thirdparty%2Fhostap.git PR: Manage Device Identity Key, password, and PMK 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 --- diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c index 341c0de7c..41144cb28 100644 --- a/src/common/proximity_ranging.c +++ b/src/common/proximity_ranging.c @@ -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) { diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h index b05dc54c7..6734e9c40 100644 --- a/src/common/proximity_ranging.h +++ b/src/common/proximity_ranging.h @@ -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); diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c index 961d5711e..bf6905e50 100644 --- a/wpa_supplicant/pr_supplicant.c +++ b/wpa_supplicant/pr_supplicant.c @@ -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); +} diff --git a/wpa_supplicant/pr_supplicant.h b/wpa_supplicant/pr_supplicant.h index 6877fa842..931d30780 100644 --- a/wpa_supplicant/pr_supplicant.h +++ b/wpa_supplicant/pr_supplicant.h @@ -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;