[RFC PATCH 1/1] wpa_supplicant: Implement SSID-based MAC address randomization
João Lucas
jlucas at disroot.org
Thu Jan 23 07:41:30 PST 2025
Signed-off-by: João Lucas <jlucas at disroot.org>
---
wpa_supplicant/config.c | 4 ++--
wpa_supplicant/config_ssid.h | 1 +
wpa_supplicant/wpa_supplicant.c | 29 +++++++++++++++++++++++++++++
3 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 228b1b2c9..b127f899e 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2729,7 +2729,7 @@ static const struct parse_data ssid_fields[] = {
{ INT(update_identifier) },
{ STR_RANGE(roaming_consortium_selection, 0, MAX_ROAMING_CONS_OI_LEN) },
#endif /* CONFIG_HS20 */
- { INT_RANGE(mac_addr, 0, 3) },
+ { INT_RANGE(mac_addr, 0, 4) },
{ FUNC_KEY(mac_value) },
{ INT_RANGE(pbss, 0, 2) },
{ INT_RANGE(wps_disabled, 0, 1) },
@@ -5562,7 +5562,7 @@ static const struct global_parse_data global_fields[] = {
{ STR(osu_dir), 0 },
{ STR(wowlan_triggers), CFG_CHANGED_WOWLAN_TRIGGERS },
{ INT(p2p_search_delay), 0},
- { INT_RANGE(mac_addr, 0, 2), 0 },
+ { INT_RANGE(mac_addr, 0, 4), 0 },
{ INT(rand_addr_lifetime), 0 },
{ INT_RANGE(preassoc_mac_addr, 0, 2), 0 },
{ INT(key_mgmt_offload), 0},
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index c5a9dbccc..a14af3952 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -77,6 +77,7 @@ enum wpas_mac_addr_style {
WPAS_MAC_ADDR_STYLE_RANDOM = 1,
WPAS_MAC_ADDR_STYLE_RANDOM_SAME_OUI = 2,
WPAS_MAC_ADDR_STYLE_DEDICATED_PER_ESS = 3,
+ WPAS_MAC_ADDR_STYLE_DERIVED_FROM_ESS = 4,
};
/**
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 132d91598..df520609e 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -20,6 +20,7 @@
#include "crypto/crypto.h"
#include "crypto/random.h"
#include "crypto/sha1.h"
+#include "crypto/sha256.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "eap_peer/eap.h"
#include "eap_peer/eap_proxy.h"
@@ -2558,6 +2559,25 @@ void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
radio_work_done(work);
}
+int random_mac_addr_from_ssid(u8 *addr, struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid)
+{
+ u8 digest[32];
+ const u8 *data[] = {ssid->ssid, wpa_s->perm_addr};
+ const size_t len[] = {ssid->ssid_len, ETH_ALEN};
+
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Deriving MAC addr from SSID: '%s' and perm_addr " MACSTR, ssid->ssid,
+ MAC2STR(wpa_s->perm_addr));
+
+ if (sha256_vector(2, data, len, digest) < 0)
+ return -1;
+
+ os_memcpy(addr, digest, ETH_ALEN);
+ addr[0] &= 0xfe; /* unicast */
+ addr[0] |= 0x02; /* locally administered */
+ return 0;
+}
int wpas_update_random_addr(struct wpa_supplicant *wpa_s,
enum wpas_mac_addr_style style,
@@ -2605,6 +2625,15 @@ int wpas_update_random_addr(struct wpa_supplicant *wpa_s,
}
os_memcpy(addr, ssid->mac_value, ETH_ALEN);
break;
+ case WPAS_MAC_ADDR_STYLE_DERIVED_FROM_ESS:
+ if (!ssid) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Invalid 'ssid' for address policy 4");
+ return -1;
+ }
+ if (random_mac_addr_from_ssid(addr, wpa_s, ssid) < 0)
+ return -1;
+ break;
default:
return -1;
}
--
2.45.3
More information about the Hostap
mailing list