From ad00d64e7d8827b3cebd665a0ceb08adabf15e1e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 1 Oct 2015 18:51:04 +0300 Subject: [PATCH] Fix TK configuration to the driver in EAPOL-Key 3/4 retry case Commit 7d711541dced759b34313477d5d163e65c5b0131 ('Clear TK part of PTK after driver key configuration') started clearing TK from memory immediately after having configured it to the driver when processing EAPOL-Key message 3/4. While this covered the most common case, it did not take into account the possibility of the authenticator having to retry EAPOL-Key message 3/4 in case the first EAPOL-Key message 4/4 response is lost. That case ended up trying to reinstall the same TK to the driver, but the key was not available anymore. Fix the EAPOL-Key message 3/4 retry case by configuring TK to the driver only once. There was no need to try to set the same key after each EAPOL-Key message 3/4 since TK could not change. If actual PTK rekeying is used, the new TK will be configured once when processing the new EAPOL-Key message 3/4 for the first time. Signed-off-by: Jouni Malinen --- src/rsn_supp/wpa.c | 8 ++++++++ src/rsn_supp/wpa_i.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index a9f255e37..f1f65c61a 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -500,6 +500,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, os_memset(buf, 0, sizeof(buf)); } sm->tptk_set = 1; + sm->tk_to_set = 1; kde = sm->assoc_wpa_ie; kde_len = sm->assoc_wpa_ie_len; @@ -605,6 +606,12 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, const u8 *key_rsc; u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + if (!sm->tk_to_set) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Do not re-install same PTK to the driver"); + return 0; + } + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Installing PTK to the driver"); @@ -643,6 +650,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, /* TK is not needed anymore in supplicant */ os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN); + sm->tk_to_set = 0; if (sm->wpa_ptk_rekey) { eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 965a9c1d5..939e0a990 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -24,6 +24,7 @@ struct wpa_sm { struct wpa_ptk ptk, tptk; int ptk_set, tptk_set; unsigned int msg_3_of_4_ok:1; + unsigned int tk_to_set:1; u8 snonce[WPA_NONCE_LEN]; u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */ int renew_snonce;