Allow group key handshake message 1/2 to be retransmitted for testing
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>
This commit is contained in:
parent
16579769ff
commit
6bc2f00f44
3 changed files with 80 additions and 0 deletions
|
@ -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))
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue