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/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;