mesh: Remove GTKdata and IGTKdata from Mesh Peering Confirm/Close
authorJouni Malinen <j@w1.fi>
Tue, 28 Jun 2016 19:23:42 +0000 (22:23 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 28 Jun 2016 19:23:42 +0000 (22:23 +0300)
These optional fields are supposed to be included in the Authenticated
Mesh Peering Exchange element only in Mesh Peering Open frames.
Previously, these were incorrectly included in Mesh Peering
Confirm/Close frames and also required to be present in all these
frames.

While this commit changes the receive processing to ignore the
unexpected extra fields, it should be noted that the previous
implementation required the fields to be present and as such, the fixed
implementation is not compatible with it for secure mesh.

Signed-off-by: Jouni Malinen <j@w1.fi>
wpa_supplicant/mesh_rsn.c

index 2eec227..cc600e2 100644 (file)
@@ -504,9 +504,11 @@ int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta,
        int ret = 0;
        size_t len;
 
-       len = sizeof(*ampe) + rsn->mgtk_len + WPA_KEY_RSC_LEN + 4;
+       len = sizeof(*ampe);
+       if (cat[1] == PLINK_OPEN)
+               len += rsn->mgtk_len + WPA_KEY_RSC_LEN + 4;
 #ifdef CONFIG_IEEE80211W
-       if (rsn->igtk_len)
+       if (cat[1] == PLINK_OPEN && rsn->igtk_len)
                len += 2 + 6 + rsn->igtk_len;
 #endif /* CONFIG_IEEE80211W */
 
@@ -532,6 +534,8 @@ int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta,
        os_memcpy(ampe->peer_nonce, sta->peer_nonce, WPA_NONCE_LEN);
 
        pos = (u8 *) (ampe + 1);
+       if (cat[1] != PLINK_OPEN)
+               goto skip_keys;
 
        /* TODO: Key Replay Counter[8] optionally for
         * Mesh Group Key Inform/Acknowledge frames */
@@ -563,6 +567,7 @@ int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta,
        }
 #endif /* CONFIG_IEEE80211W */
 
+skip_keys:
        wpa_hexdump_key(MSG_DEBUG, "mesh: Plaintext AMPE element",
                        ampe_ie, 2 + len);
 
@@ -683,6 +688,28 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
         * frames */
 
        /*
+        * GTKdata shall not be included in Mesh Peering Confirm. While the
+        * standard does not state the same about IGTKdata, that same constraint
+        * needs to apply for it. It makes no sense to include the keys in Mesh
+        * Peering Close frames either, so while the standard does not seem to
+        * have a shall statement for these, they are described without
+        * mentioning GTKdata.
+        *
+        * An earlier implementation used to add GTKdata to both Mesh Peering
+        * Open and Mesh Peering Confirm frames, so ignore the possibly present
+        * GTKdata frame without rejecting the frame as a backwards
+        * compatibility mechanism.
+        */
+       if (cat[1] != PLINK_OPEN) {
+               if (end > pos) {
+                       wpa_hexdump_key(MSG_DEBUG,
+                                       "mesh: Ignore unexpected GTKdata(etc.) fields in the end of AMPE element in Mesh Peering Confirm/Close",
+                                       pos, end - pos);
+               }
+               goto free;
+       }
+
+       /*
         * GTKdata[variable]:
         * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4]
         */