]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mesh: Check PMKID in AMPE Action frames
authorBob Copeland <me@bobcopeland.com>
Sun, 27 Dec 2015 02:20:52 +0000 (21:20 -0500)
committerJouni Malinen <j@w1.fi>
Mon, 28 Dec 2015 15:21:08 +0000 (17:21 +0200)
From IEEE Std 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@bobcopeland.com>
wpa_supplicant/mesh_mpm.c
wpa_supplicant/mesh_rsn.c
wpa_supplicant/mesh_rsn.h

index 7ebd4d2e686c6523d205ea6aef62c1700ccd4127..3259151a58f82a5c3db1565b9a665d21dbb8495f 100644 (file)
@@ -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;
index 8150ff197be2d336d18c001f6f6ee6a233adb9c9..5d88274b8678ea914e3224f82c7e86f6f2ef223d 100644 (file)
@@ -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,12 @@ 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 (Chosen PMK did not match calculated 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;
index b1471b2de8ae918180719780bd9f1f31caf63d06..89601d4075799925b34bb75a0cc3d181e441c893 100644 (file)
@@ -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);