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;
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)
{
#ifndef PROXIMITY_RANGING_H
#define PROXIMITY_RANGING_H
+#include "wpa_common.h"
#include "utils/list.h"
#include "wps/wps_defs.h"
#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
*/
* 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;
};
/* 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
*/
struct pr_config *cfg;
struct dl_list devices;
+
+ struct dl_list dev_iks;
};
/* PR Device Identity Resolution Attribute parameters */
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);
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);
+}
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,
{
}
+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;