[PATCH 2/2] mesh: check PMKID in AMPE action frames

Bob Copeland me at bobcopeland.com
Sat Dec 26 18:20:52 PST 2015


>From 802.11-2012 13.3.5:

   If the incoming Mesh Peering Management frame is for AMPE and the Chosen
   PMK from the received frame contains a PMKID that does not identify a valid
   mesh PMKSA, the frame shall be silently discarded.

We were not checking the PMKID previously, and we also weren't parsing it
correctly, so fix both.

Signed-off-by: Bob Copeland <me at bobcopeland.com>
---
 wpa_supplicant/mesh_mpm.c | 3 ++-
 wpa_supplicant/mesh_rsn.c | 6 ++++++
 wpa_supplicant/mesh_rsn.h | 1 +
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 7ebd4d2e686c..3259151a58f8 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -74,8 +74,8 @@ static int mesh_mpm_parse_peer_mgmt(struct wpa_supplicant *wpa_s,
 
 	/* remove optional PMK at end */
 	if (len >= 16) {
-		len -= 16;
 		mpm_ie->pmk = ie + len - 16;
+		len -= 16;
 	}
 
 	if ((action_field == PLINK_OPEN && len != 4) ||
@@ -1014,6 +1014,7 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
 	if ((mconf->security & MESH_CONF_SEC_AMPE) &&
 	    mesh_rsn_process_ampe(wpa_s, sta, &elems,
 				  &mgmt->u.action.category,
+				  peer_mgmt_ie.pmk,
 				  ies, ie_len)) {
 		wpa_printf(MSG_DEBUG, "MPM: RSN process rejected frame");
 		return;
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index 8150ff197be2..1a0340516bb7 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -500,6 +500,7 @@ free:
 
 int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
 			  struct ieee802_11_elems *elems, const u8 *cat,
+			  const u8 *chosen_pmk,
 			  const u8 *start, size_t elems_len)
 {
 	int ret = 0;
@@ -513,6 +514,11 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
 	const size_t aad_len[] = { ETH_ALEN, ETH_ALEN,
 				   (elems->mic - 2) - cat };
 
+	if (chosen_pmk && os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN)) {
+		wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid PMKID");
+		return -1;
+	}
+
 	if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) {
 		wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie");
 		return -1;
diff --git a/wpa_supplicant/mesh_rsn.h b/wpa_supplicant/mesh_rsn.h
index b1471b2de8ae..89601d407579 100644
--- a/wpa_supplicant/mesh_rsn.h
+++ b/wpa_supplicant/mesh_rsn.h
@@ -30,6 +30,7 @@ int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta,
 			   const u8 *cat, struct wpabuf *buf);
 int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
 			  struct ieee802_11_elems *elems, const u8 *cat,
+			  const u8 *chosen_pmk,
 			  const u8 *start, size_t elems_len);
 void mesh_auth_timer(void *eloop_ctx, void *user_data);
 
-- 
2.6.1




More information about the Hostap mailing list