[PATCH 1/3] FT: check mobility domain with RRB
Michael Braun
michael-dev at fami-braun.de
Sun Sep 25 02:09:06 PDT 2016
A malcious client might try to roam between different Mobility Domains, if the
APs share their encryption key and reach each other using ft_iface.
This change makes hostapd check the mobility domain with push and pull reply
messages.
Signed-off-by: Michael Braun <michael-dev at fami-braun.de>
---
src/ap/wpa_auth.h | 1 +
src/ap/wpa_auth_ft.c | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 15994bf..650cad2 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -83,6 +83,7 @@ struct ft_rrb_frame {
#define FT_RRB_IDENTITY 14
#define FT_RRB_RADIUS_CUI 15
#define FT_RRB_SESSION_TIMEOUT 16 /* le32 seconds */
+#define FT_RRB_MOBILITY_DOMAIN 17 /* MOBILITY_DOMAIN_ID_LEN */
struct ft_rrbv1_tlv {
le16 type;
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 9d85eb0..8d125af 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -2482,6 +2482,7 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
size_t f_nonce_len, f_r0kh_id_len, f_r1kh_id_len, f_s1kh_id_len;
size_t f_pmk_r0_name_len;
const struct wpa_ft_pmk_r0_sa *r0;
+ const u8 *mdid = wpa_auth->conf.mobility_domain;
wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull request");
@@ -2551,6 +2552,9 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
.data = f_r1kh_id },
{ .type = FT_RRB_S1KH_ID, .len = f_s1kh_id_len,
.data = f_s1kh_id },
+ { .type = FT_RRB_MOBILITY_DOMAIN,
+ .len = MOBILITY_DOMAIN_ID_LEN,
+ .data = mdid },
{ .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL },
};
@@ -2661,11 +2665,13 @@ static int wpa_ft_rrb_rx_r1(struct wpa_authenticator *wpa_auth,
const u8 *f_expires_in;
const u8 *f_identity, *f_radius_cui;
const u8 *f_session_timeout;
+ const u8 *f_mobility_domain;
size_t f_r1kh_id_len, f_s1kh_id_len;
size_t f_pmk_r1_name_len, f_pairwise_len, f_pmk_r1_len;
size_t f_expires_in_len;
size_t f_identity_len, f_radius_cui_len;
size_t f_session_timeout_len;
+ size_t f_mobility_domain_len;
int pairwise;
int ret = -1;
int expires_in;
@@ -2673,6 +2679,7 @@ static int wpa_ft_rrb_rx_r1(struct wpa_authenticator *wpa_auth,
int session_timeout;
struct vlan_description vlan;
char buf[256];
+ const u8 *mdid = wpa_auth->conf.mobility_domain;
RRB_GET(FT_RRB_R1KH_ID, r1kh_id, msgtype, FT_R1KH_ID_LEN);
if (os_memcmp_const(f_r1kh_id, wpa_auth->conf.r1_key_holder,
@@ -2700,6 +2707,21 @@ static int wpa_ft_rrb_rx_r1(struct wpa_authenticator *wpa_auth,
wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name",
f_pmk_r1_name, WPA_PMK_NAME_LEN);
+ RRB_GET_OPTIONAL(FT_RRB_MOBILITY_DOMAIN, mobility_domain, msgtype,
+ MOBILITY_DOMAIN_ID_LEN);
+ if (f_mobility_domain) {
+ os_snprintf(buf, sizeof(buf), "FT: PMK-R1 %s - Mobility Domain",
+ msgtype);
+ wpa_hexdump(MSG_DEBUG, buf, f_mobility_domain,
+ f_mobility_domain_len);
+ }
+ if (f_mobility_domain &&
+ os_memcmp(mdid, f_mobility_domain, MOBILITY_DOMAIN_ID_LEN) != 0) {
+ wpa_printf(MSG_DEBUG, "FT: PMK-R1 %s did not use a matching "
+ "Mobility Domain", msgtype);
+ goto out;
+ }
+
pairwise = WPA_GET_LE16(f_pairwise);
RRB_GET_OPTIONAL(FT_RRB_EXPIRES_IN, expires_in, msgtype,
@@ -3050,6 +3072,7 @@ static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
u8 *packet;
size_t packet_len;
u8 f_timestamp[sizeof(le32)];
+ const u8 *mdid = wpa_auth->conf.mobility_domain;
os_memset(&push_hdr, 0, sizeof(push_hdr));
push_hdr.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
@@ -3068,6 +3091,9 @@ static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
.data = s1kh_id },
{ .type = FT_RRB_PMK_R0_NAME, .len = WPA_PMK_NAME_LEN,
.data = pmk_r0->pmk_r0_name },
+ { .type = FT_RRB_MOBILITY_DOMAIN,
+ .len = MOBILITY_DOMAIN_ID_LEN,
+ .data = mdid },
{ .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL },
};
--
2.1.4
More information about the Hostap
mailing list