p2p: support random device address
To enhance privacy, generate a ramdom device address for p2p interface.
If there is no saved persistent group, it generate a new random MAC address on bringing up p2p0.
If there is saved persistent group, it will use last MAC address to avoid breaking
group reinvoke behavior.
There are two configurations are introduced:
* p2p_device_random_mac_addr
enable device random MAC address feature, default disable.
* p2p_device_persistent_mac_addr
store last used random MAC address.
Bug: 118904478
Test: manual test (Without saved persistent groups)
* enable WiFi Direct in Settings.
* check MAC address is changed on bringing up p2p0 everytime.
* establish fresh connection between two peers.
* establish reinvoke connection between two peers.
Test: manual test (With saved ersistent groups)
* enable WiFi Direct in Settings.
* ensure MAC address is restored to last used MAC address.
* establish fresh connection between two peers.
* establish reinvoke connection between two peers.
Test: CtsVerifier - WiFi Direct
* Two random device address enabled device.
* One random device address enabled device and
One random device address disabled device.
Change-Id: I3a519209752e0e79c82c7fbd9c7a18669f778e84
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index dd7f603..970e0fa 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2637,6 +2637,7 @@
#ifdef CONFIG_MBO
os_free(config->non_pref_chan);
#endif /* CONFIG_MBO */
+ os_free(config->p2p_device_persistent_mac_addr);
os_free(config);
}
@@ -4753,6 +4754,8 @@
{ INT(gas_rand_addr_lifetime), 0 },
{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
+ { INT(p2p_device_random_mac_addr), 0 },
+ { STR(p2p_device_persistent_mac_addr), 0 },
};
#undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index ad4dd88..4677d48 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1469,6 +1469,26 @@
* profile automatically
*/
int dpp_config_processing;
+
+ /**
+ * p2p_device_random_mac_addr - P2P Device MAC address policy default
+ *
+ * 0 = use permanent MAC address
+ * 1 = use random MAC address on creating the interface if there is no persistent groups.
+ *
+ * By default, permanent MAC address is used.
+ */
+ int p2p_device_random_mac_addr;
+
+ /**
+ * p2p_device_persistent_mac_addr - Record last used MAC address
+ *
+ * If there are saved persistent groups, P2P cannot generate another random MAC address,
+ * and need to restore to last used MAC address.
+ * format: aa:bb:cc:dd:ee:ff
+ */
+ char *p2p_device_persistent_mac_addr;
+
};
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index aa73f9d..cab4244 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1511,6 +1511,12 @@
if (config->dpp_config_processing)
fprintf(f, "dpp_config_processing=%d\n",
config->dpp_config_processing);
+ if (config->p2p_device_random_mac_addr)
+ fprintf(f, "p2p_device_random_mac_addr=%d\n",
+ config->p2p_device_random_mac_addr);
+ if (config->p2p_device_persistent_mac_addr)
+ fprintf(f, "p2p_device_persistent_mac_addr=%s\n",
+ config->p2p_device_persistent_mac_addr);
}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index b9b0bea..346326f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -4314,6 +4314,57 @@
WPA_IF_P2P_CLIENT, len, freq_list);
}
+int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s)
+{
+ u8 addr[ETH_ALEN] = {0};
+
+ if (wpa_s->conf->p2p_device_random_mac_addr == 0)
+ return 0;
+
+ if (wpa_s->conf->ssid == NULL) {
+ if (random_mac_addr(addr) < 0) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Failed to generate random MAC address");
+ return -EINVAL;
+ }
+
+ // store generated MAC address.
+ if (wpa_s->conf->p2p_device_persistent_mac_addr)
+ os_free(wpa_s->conf->p2p_device_persistent_mac_addr);
+ size_t mac_addr_str_len = sizeof("00:00:00:00:00:00");
+ wpa_s->conf->p2p_device_persistent_mac_addr =
+ os_zalloc(mac_addr_str_len + 1);
+ os_snprintf(wpa_s->conf->p2p_device_persistent_mac_addr,
+ mac_addr_str_len, MACSTR, MAC2STR(addr));
+ } else {
+ // If there are existing saved groups, restore last MAC address.
+ // if there is no last used MAC address, the last one is factory MAC.
+ if (!wpa_s->conf->p2p_device_persistent_mac_addr)
+ return 0;
+
+ if (hwaddr_aton(wpa_s->conf->p2p_device_persistent_mac_addr, addr) < 0)
+ return -EINVAL;
+ wpa_msg(wpa_s, MSG_DEBUG, "Restore last used MAC address.");
+ }
+
+ if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Failed to set random MAC address");
+ return -EINVAL;
+ }
+
+ if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Could not update MAC address information");
+ return -EINVAL;
+ }
+
+ wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
+ MAC2STR(addr));
+
+ return 0;
+}
+
/**
* wpas_p2p_init - Initialize P2P module for %wpa_supplicant
@@ -4335,6 +4386,12 @@
if (global->p2p)
return 0;
+ if (wpas_p2p_mac_setup(wpa_s) < 0) {
+ wpa_msg(wpa_s, MSG_ERROR,
+ "Failed to initialize P2P random MAC address.");
+ return -1;
+ }
+
os_memset(&p2p, 0, sizeof(p2p));
p2p.cb_ctx = wpa_s;
p2p.debug_print = wpas_p2p_debug_print;
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 63910d1..0a08a88 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -211,6 +211,7 @@
unsigned int period, unsigned int interval,
unsigned int count);
int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s);
+int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s);
#else /* CONFIG_P2P */