From c5f0a609c8a830d5bb01ec02f156bd72358b7fd1 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Tue, 6 Apr 2021 18:08:44 +0530 Subject: [PATCH 1/2] wpa_supplicant: Prevent reinstallation of an already in-use group key --- .../wpa_supplicant/src/common/wpa_common.h | 5 +++++ components/wpa_supplicant/src/rsn_supp/wpa.c | 16 ++++++++++++++-- components/wpa_supplicant/src/rsn_supp/wpa_i.h | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index f88e8a6fac..2a25a03874 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -172,6 +172,11 @@ struct wpa_ptk { } u; } STRUCT_PACKED; +struct wpa_gtk { + u8 gtk[WPA_GTK_MAX_LEN]; + size_t gtk_len; +}; + struct wpa_gtk_data { enum wpa_alg alg; int tx, key_rsc_len, keyidx; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 074393b016..41cccca80a 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -805,11 +805,20 @@ int wpa_supplicant_install_gtk(struct wpa_sm *sm, wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); - #ifdef DEBUG_PRINT + /* Detect possible key reinstallation */ + if (sm->gtk.gtk_len == (size_t) gd->gtk_len && + os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) { + wpa_printf(MSG_DEBUG, + "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", + gd->keyidx, gd->tx, gd->gtk_len); + return 0; + } + #ifdef DEBUG_PRINT wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver " "(keyidx=%d tx=%d len=%d).\n", gd->keyidx, gd->tx, gd->gtk_len); - #endif + #endif + wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len); if (sm->group_cipher == WPA_CIPHER_TKIP) { /* Swap Tx/Rx keys for Michael MIC */ @@ -843,6 +852,9 @@ int wpa_supplicant_install_gtk(struct wpa_sm *sm, return -1; } + sm->gtk.gtk_len = gd->gtk_len; + os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); + return 0; } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index e0242fbcb7..458a635e6a 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -41,6 +41,7 @@ struct wpa_sm { u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; int rx_replay_counter_set; u8 request_counter[WPA_REPLAY_COUNTER_LEN]; + struct wpa_gtk gtk; struct rsn_pmksa_cache *pmksa; /* PMKSA cache */ struct rsn_pmksa_cache_entry *cur_pmksa; /* current PMKSA entry */ From 39a3d1df8e2522516087ef1acedb1e9b5d155fc0 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Thu, 22 Apr 2021 13:05:49 +0530 Subject: [PATCH 2/2] wpa_supplicant: Group key reinstallation fixes This commit reverts previous commit for GTK reinstallation fix and corrects original fix. --- .../wpa_supplicant/src/common/wpa_common.h | 5 ---- components/wpa_supplicant/src/rsn_supp/wpa.c | 30 +++++-------------- .../wpa_supplicant/src/rsn_supp/wpa_i.h | 1 - 3 files changed, 7 insertions(+), 29 deletions(-) diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index 2a25a03874..f88e8a6fac 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -172,11 +172,6 @@ struct wpa_ptk { } u; } STRUCT_PACKED; -struct wpa_gtk { - u8 gtk[WPA_GTK_MAX_LEN]; - size_t gtk_len; -}; - struct wpa_gtk_data { enum wpa_alg alg; int tx, key_rsc_len, keyidx; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 41cccca80a..a8cd88b504 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -63,6 +63,7 @@ int wpa_sm_get_key(uint8_t *ifx, int *alg, u8 *addr, int *key_idx, u8 *key, size void wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len); void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm); +static bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd); static inline enum wpa_states wpa_sm_get_state(struct wpa_sm *sm) { return sm->wpa_state;; @@ -806,8 +807,7 @@ int wpa_supplicant_install_gtk(struct wpa_sm *sm, wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); /* Detect possible key reinstallation */ - if (sm->gtk.gtk_len == (size_t) gd->gtk_len && - os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) { + if (wpa_supplicant_gtk_in_use(sm, &(sm->gd))) { wpa_printf(MSG_DEBUG, "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", gd->keyidx, gd->tx, gd->gtk_len); @@ -852,13 +852,10 @@ int wpa_supplicant_install_gtk(struct wpa_sm *sm, return -1; } - sm->gtk.gtk_len = gd->gtk_len; - os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); - return 0; } -bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd) +static bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd) { u8 *_gtk = gd->gtk; u8 gtk_buf[32]; @@ -868,8 +865,6 @@ bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd) u8 bssid[6]; int keyidx; - wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); - #ifdef DEBUG_PRINT wpa_printf(MSG_DEBUG, "WPA: Judge GTK: (keyidx=%d len=%d).", gd->keyidx, gd->gtk_len); #endif @@ -882,19 +877,10 @@ bool wpa_supplicant_gtk_in_use(struct wpa_sm *sm, struct wpa_gtk_data *gd) _gtk = gtk_buf; } - //check if gtk is in use. - if (wpa_sm_get_key(&ifx, &alg, bssid, &keyidx, gtk_get, gd->gtk_len, gd->keyidx) == 0) { + if (wpa_sm_get_key(&ifx, &alg, bssid, &keyidx, gtk_get, gd->gtk_len, gd->keyidx - 2) == 0) { if (ifx == 0 && alg == gd->alg && memcmp(bssid, sm->bssid, ETH_ALEN) == 0 && memcmp(_gtk, gtk_get, gd->gtk_len) == 0) { - wpa_printf(MSG_DEBUG, "GTK %d is already in use in entry %d, it may be an attack, ignor it.", gd->keyidx, gd->keyidx + 2); - return true; - } - } - - if (wpa_sm_get_key(&ifx, &alg, bssid, &keyidx, gtk_get, gd->gtk_len, (gd->keyidx+1)%2) == 0) { - if (ifx == 0 && alg == gd->alg && memcmp(bssid, sm->bssid, ETH_ALEN) == 0 && - memcmp(_gtk, gtk_get, gd->gtk_len) == 0) { - wpa_printf(MSG_DEBUG, "GTK %d is already in use in entry %d, it may be an attack, ignor it.", gd->keyidx, (gd->keyidx+1)%2 + 2); + wpa_printf(MSG_DEBUG, "GTK %d is already in use in entry %d, it may be an attack, ignore it.", gd->keyidx, hw_keyidx); return true; } } @@ -1573,10 +1559,8 @@ failed: u16 rekey= (WPA_SM_STATE(sm) == WPA_COMPLETED); if((sm->gd).gtk_len) { - if (wpa_supplicant_gtk_in_use(sm, &(sm->gd)) == false) { - if (wpa_supplicant_install_gtk(sm, &(sm->gd))) - goto failed; - } + if (wpa_supplicant_install_gtk(sm, &(sm->gd))) + goto failed; } else { goto failed; } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index 458a635e6a..e0242fbcb7 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -41,7 +41,6 @@ struct wpa_sm { u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; int rx_replay_counter_set; u8 request_counter[WPA_REPLAY_COUNTER_LEN]; - struct wpa_gtk gtk; struct rsn_pmksa_cache *pmksa; /* PMKSA cache */ struct rsn_pmksa_cache_entry *cur_pmksa; /* current PMKSA entry */