]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
RSN IBSS: Fix TK clearing on Authentication frame RX
authorJouni Malinen <j@w1.fi>
Sat, 14 Jan 2017 11:56:18 +0000 (13:56 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 14 Jan 2017 11:56:18 +0000 (13:56 +0200)
When wpa_supplicant was processing a received Authentication frame (seq
1) from a peer STA for which there was already a TK configured to the
driver, debug log claimed that the PTK gets cleared, but the actual
call to clear the key was actually dropped due to AUTH vs. SUPP set_key
selection. Fix this by explicitly clearing the TK in case it was set
and an Authentication frame (seq 1) is received.

This fixes some cases where EAPOL-Key frames were sent encrypted using
the old key when a peer STA restarted itself and lost the key and had to
re-join the IBSS. Previously, that state required timing out the 4-way
handshake and Deauthentication frame exchange to recover.

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

index 53d7d57bde350ddab93ca6ca8ef2451f4d0bdb41..c29d8d3e37f57b9bddeb0c5545d482b21dd3d6a0 100644 (file)
@@ -837,6 +837,18 @@ static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn,
        wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR,
                   MAC2STR(addr));
 
+       if (peer &&
+           peer->authentication_status & (IBSS_RSN_SET_PTK_SUPP |
+                                          IBSS_RSN_SET_PTK_AUTH)) {
+               /* Clear the TK for this pair to allow recovery from the case
+                * where the peer STA has restarted and lost its key while we
+                * still have a pairwise key configured. */
+               wpa_printf(MSG_DEBUG, "RSN: Clear pairwise key for peer "
+                          MACSTR, MAC2STR(addr));
+               wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_NONE, addr, 0, 0,
+                               NULL, 0, NULL, 0);
+       }
+
        if (peer &&
            peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) {
                if (peer->own_auth_tx.sec) {