diff mbox

[1/3] FT: check mobility domain with RRB

Message ID 1474794548-326-2-git-send-email-michael-dev@fami-braun.de
State Deferred
Headers show

Commit Message

michael-dev Sept. 25, 2016, 9:09 a.m. UTC
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@fami-braun.de>
---
 src/ap/wpa_auth.h    |  1 +
 src/ap/wpa_auth_ft.c | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)
diff mbox

Patch

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 },
 	};