]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Allow group key handshake message 1/2 to be retransmitted for testing
authorJouni Malinen <j@w1.fi>
Sat, 14 Oct 2017 13:53:27 +0000 (16:53 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 16 Oct 2017 14:47:24 +0000 (17:47 +0300)
The new hostapd control interface command "RESEND_GROUP_M1 <addr>" can
be used to request a retransmission of the Group Key Handshake message
1/2 for the current GTK.

This functionality is for testing purposes and included only in builds
with CONFIG_TESTING_OPTIONS=y.

Signed-off-by: Jouni Malinen <j@w1.fi>
hostapd/ctrl_iface.c
src/ap/wpa_auth.c
src/ap/wpa_auth.h

index 12978f79f7abe8f1573002e9733b772dc7dce4f7..247de0a1f2600853ac7fbdc47d29925a1a638124 100644 (file)
@@ -2033,6 +2033,26 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
                                   sta->last_tk, sta->last_tk_len);
 }
 
+
+static int hostapd_ctrl_resend_group_m1(struct hostapd_data *hapd,
+                                       const char *cmd)
+{
+       struct sta_info *sta;
+       u8 addr[ETH_ALEN];
+
+       if (hwaddr_aton(cmd, addr))
+               return -1;
+
+       sta = ap_get_sta(hapd, addr);
+       if (!sta || !sta->wpa_sm)
+               return -1;
+
+       wpa_printf(MSG_INFO,
+                  "TESTING: Send group M1 for the same GTK and zero RSC to "
+                  MACSTR, MAC2STR(sta->addr));
+       return wpa_auth_resend_group_m1(sta->wpa_sm);
+}
+
 #endif /* CONFIG_TESTING_OPTIONS */
 
 
@@ -2752,6 +2772,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
        } else if (os_strncmp(buf, "RESET_PN ", 9) == 0) {
                if (hostapd_ctrl_reset_pn(hapd, buf + 9) < 0)
                        reply_len = -1;
+       } else if (os_strncmp(buf, "RESEND_GROUP_M1 ", 16) == 0) {
+               if (hostapd_ctrl_resend_group_m1(hapd, buf + 16) < 0)
+                       reply_len = -1;
 #endif /* CONFIG_TESTING_OPTIONS */
        } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
                if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
index a4b8c8c77785156661e21e84998c025415a3adc5..1632072767bc9c3036a9a99db74f83914feade7d 100644 (file)
@@ -4501,3 +4501,58 @@ void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm,
 }
 
 #endif /* CONFIG_FILS */
+
+
+#if CONFIG_TESTING_OPTIONS
+int wpa_auth_resend_group_m1(struct wpa_state_machine *sm)
+{
+       u8 rsc[WPA_KEY_RSC_LEN];
+       struct wpa_group *gsm = sm->group;
+       const u8 *kde;
+       u8 *kde_buf = NULL, *pos, *opos, hdr[2];
+       size_t kde_len;
+       u8 *gtk;
+
+       /* Send EAPOL(1, 1, 1, !Pair, G, RSC, GNonce, MIC(PTK), GTK[GN]) */
+       os_memset(rsc, 0, WPA_KEY_RSC_LEN);
+       /* Use 0 RSC */
+       wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
+                       "sending 1/2 msg of Group Key Handshake (TESTING)");
+
+       gtk = gsm->GTK[gsm->GN - 1];
+       if (sm->wpa == WPA_VERSION_WPA2) {
+               kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
+                       ieee80211w_kde_len(sm);
+               kde_buf = os_malloc(kde_len);
+               if (kde_buf == NULL)
+                       return -1;
+
+               kde = pos = kde_buf;
+               hdr[0] = gsm->GN & 0x03;
+               hdr[1] = 0;
+               pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
+                                 gtk, gsm->GTK_len);
+               opos = pos;
+               pos = ieee80211w_kde_add(sm, pos);
+               if (pos - opos >= WPA_IGTK_KDE_PREFIX_LEN) {
+                       opos += 2; /* skip keyid */
+                       os_memset(opos, 0, 6); /* clear PN */
+               }
+               kde_len = pos - kde;
+       } else {
+               kde = gtk;
+               kde_len = gsm->GTK_len;
+       }
+
+       wpa_send_eapol(sm->wpa_auth, sm,
+                      WPA_KEY_INFO_SECURE |
+                      (wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?
+                       WPA_KEY_INFO_MIC : 0) |
+                      WPA_KEY_INFO_ACK |
+                      (!sm->Pair ? WPA_KEY_INFO_INSTALL : 0),
+                      rsc, NULL, kde, kde_len, gsm->GN, 1);
+
+       os_free(kde_buf);
+       return 0;
+}
+#endif /* CONFIG_TESTING_OPTIONS */
index 902d377d3224949c30b75e6b59fd0dbb00e9a1e3..ea91eda5b9ce315ff218149ae8104a30978c8a3e 100644 (file)
@@ -427,4 +427,6 @@ u8 * wpa_auth_write_assoc_resp_owe(struct wpa_state_machine *sm,
                                   u8 *pos, size_t max_len,
                                   const u8 *req_ies, size_t req_ies_len);
 
+int wpa_auth_resend_group_m1(struct wpa_state_machine *sm);
+
 #endif /* WPA_AUTH_H */