]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Fix no_encrypt flag in control port TX for rekeying
authorJouni Malinen <j@w1.fi>
Fri, 6 May 2022 21:58:41 +0000 (00:58 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 7 May 2022 15:54:09 +0000 (18:54 +0300)
The wpa_supplicant check for whether a TK is configured into the driver
was broken during the time this information is needed for rekeying or
reauthenticating with another 4-way handshake. sm->ptk.installed is not
set at the point the EAPOL-Key msg 4/4 is sent and while that means the
initial 4-way handshake needs to prevent encryption, the consecutive
4-way handshake must not be doing that since the old key (TK) is still
in the driver. Fix this so that the EAPOL-Key msg 4/4 during rekeying
does not get transmitted without encryption.

Fixes: a79ed0687197 ("Add no_encrypt flag for control port TX")
Signed-off-by: Jouni Malinen <j@w1.fi>
src/rsn_supp/wpa.c
src/rsn_supp/wpa_ft.c
src/rsn_supp/wpa_i.h

index 7758c23935e2b23327217eb5112c048ea8de6068..30061e1f030297d6ffab757675615be4ec0ea357 100644 (file)
@@ -972,6 +972,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
        os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
        sm->ptk.tk_len = 0;
        sm->ptk.installed = 1;
+       sm->tk_set = true;
 
        if (sm->wpa_ptk_rekey) {
                eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
@@ -3066,6 +3067,7 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
                os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
                os_memset(&sm->igtk, 0, sizeof(sm->igtk));
                os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
+               sm->tk_set = false;
        }
 
 #ifdef CONFIG_TDLS
@@ -3853,6 +3855,7 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
        wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
        sm->ptk_set = 0;
        sm->tptk_set = 0;
+       sm->tk_set = false;
        sm->pmk_len = 0;
        os_memset(sm->pmk, 0, sizeof(sm->pmk));
        os_memset(&sm->ptk, 0, sizeof(sm->ptk));
@@ -3889,7 +3892,7 @@ int wpa_sm_has_ptk_installed(struct wpa_sm *sm)
 {
        if (!sm)
                return 0;
-       return sm->ptk.installed;
+       return sm->tk_set || sm->ptk.installed;
 }
 
 
@@ -4995,6 +4998,7 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
        os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
        sm->ptk.tk_len = 0;
        sm->ptk.installed = 1;
+       sm->tk_set = true;
 
        /* FILS HLP Container */
        fils_process_hlp_container(sm, ie_start, end - ie_start);
index 2669da9b3fa8904320c0765d74cfa43642d204cf..95c1e73ef116e0e59775dc94af08cf31a8364f46 100644 (file)
@@ -467,6 +467,7 @@ static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
                wpa_printf(MSG_WARNING, "FT: Failed to set PTK to the driver");
                return -1;
        }
+       sm->tk_set = true;
 
        wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher,
                         sm->dot11RSNAConfigPMKLifetime, &sm->ptk);
index 579616fbbeaf9ccfa5c3f5551bb1cd821b33021e..fabd6cb26bea1d3dcd59c7ff61d9663a76d800ff 100644 (file)
@@ -27,6 +27,7 @@ struct wpa_sm {
        size_t pmk_len;
        struct wpa_ptk ptk, tptk;
        int ptk_set, tptk_set;
+       bool tk_set; /* Whether any TK is configured to the driver */
        unsigned int msg_3_of_4_ok:1;
        u8 snonce[WPA_NONCE_LEN];
        u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */