[PATCH v2 10/17] MLD STA: Add support for processing EAPOL 3/4 frame
Veerendranath Jakkam
quic_vjakkam at quicinc.com
Sat Oct 1 01:21:22 PDT 2022
Process EAPOL 3/4 frame and plumb PTK and per-link GTK/IGTK/BIGTK keys
to driver.
Signed-off-by: Veerendranath Jakkam <quic_vjakkam at quicinc.com>
---
src/rsn_supp/wpa.c | 474 ++++++++++++++++++++++++++++++++++++++++++++++++++-
src/rsn_supp/wpa_i.h | 6 +
2 files changed, 478 insertions(+), 2 deletions(-)
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 5611da3..5d1ff43 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -1220,6 +1220,64 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
}
+static int wpa_supplicant_install_mlo_gtk(struct wpa_sm *sm, u8 link_id,
+ const struct wpa_gtk_data *gd,
+ const u8 *key_rsc, int wnm_sleep)
+{
+ const u8 *gtk = gd->gtk;
+ u8 gtk_buf[32];
+ char title[50];
+ int ret;
+
+ /* Detect possible key reinstallation */
+ if ((sm->mlo.links[link_id].gtk.gtk_len == (size_t) gd->gtk_len &&
+ os_memcmp(sm->mlo.links[link_id].gtk.gtk, gd->gtk,
+ sm->mlo.links[link_id].gtk.gtk_len) == 0) ||
+ (sm->mlo.links[link_id].gtk_wnm_sleep.gtk_len ==
+ (size_t) gd->gtk_len &&
+ os_memcmp(sm->mlo.links[link_id].gtk_wnm_sleep.gtk, gd->gtk,
+ sm->mlo.links[link_id].gtk_wnm_sleep.gtk_len) == 0)) {
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: Not reinstalling already in-use GTK to the driver (link_id=%d keyidx=%d tx=%d len=%d)",
+ link_id, gd->keyidx, gd->tx, gd->gtk_len);
+ return 0;
+ }
+
+ ret = os_snprintf(title, sizeof(title), "RSN: Link %u Group Key",
+ link_id);
+ if (!os_snprintf_error(sizeof(title), ret))
+ wpa_hexdump_key(MSG_DEBUG, title, gd->gtk, gd->gtk_len);
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: Installing GTK to the driver (link_id=%d keyidx=%d tx=%d len=%d)",
+ link_id, gd->keyidx, gd->tx, gd->gtk_len);
+ ret = os_snprintf(title, sizeof(title), "RSN: Link %u RSC", link_id);
+ if (!os_snprintf_error(sizeof(title), ret))
+ wpa_hexdump(MSG_DEBUG, title, key_rsc, gd->key_rsc_len);
+ if (wpa_sm_set_key(sm, link_id, gd->alg, broadcast_ether_addr,
+ gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len, gtk,
+ gd->gtk_len, KEY_FLAG_GROUP_RX) < 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "RSN: Failed to set GTK to the driver (link_id=%d alg=%d keylen=%d keyidx=%d)",
+ link_id, gd->alg, gd->gtk_len, gd->keyidx);
+ forced_memzero(gtk_buf, sizeof(gtk_buf));
+ return -1;
+ }
+ forced_memzero(gtk_buf, sizeof(gtk_buf));
+
+ if (wnm_sleep) {
+ sm->mlo.links[link_id].gtk_wnm_sleep.gtk_len = gd->gtk_len;
+ os_memcpy(sm->mlo.links[link_id].gtk_wnm_sleep.gtk, gd->gtk,
+ sm->mlo.links[link_id].gtk_wnm_sleep.gtk_len);
+ } else {
+ sm->mlo.links[link_id].gtk.gtk_len = gd->gtk_len;
+ os_memcpy(sm->mlo.links[link_id].gtk.gtk, gd->gtk,
+ sm->mlo.links[link_id].gtk.gtk_len);
+ }
+
+ return 0;
+}
+
+
static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
int tx)
{
@@ -1268,6 +1326,87 @@ static int wpa_supplicant_rsc_relaxation(const struct wpa_sm *sm,
}
+static int wpa_supplicant_mlo_gtk(struct wpa_sm *sm, u8 link_id, const u8 *gtk,
+ size_t gtk_len, int key_info)
+{
+ struct wpa_gtk_data gd;
+ const u8 *key_rsc;
+ char title[100];
+ int ret;
+
+ /*
+ * MLO GTK KDE format:
+ * KeyID[bits 0-1], Tx [bit 2], Reserved [bit 3], link id [4-7]
+ * PN
+ * GTK
+ */
+ os_memset(&gd, 0, sizeof(gd));
+ ret = os_snprintf(title, sizeof(title),
+ "RSN: received link %u GTK in pairwise handshake",
+ link_id);
+ if (!os_snprintf_error(sizeof(title), ret))
+ wpa_hexdump_key(MSG_DEBUG, title, gtk, gtk_len);
+
+ if (gtk_len < RSN_MLO_GTK_KDE_PREFIX_LENGTH ||
+ gtk_len - RSN_MLO_GTK_KDE_PREFIX_LENGTH > sizeof(gd.gtk))
+ return -1;
+
+ gd.keyidx = gtk[0] & 0x3;
+ gtk += 1;
+ gtk_len -= 1;
+
+ key_rsc = gtk;
+
+ gtk += 6;
+ gtk_len -= 6;
+
+ os_memcpy(gd.gtk, gtk, gtk_len);
+ gd.gtk_len = gtk_len;
+
+ ret = 0;
+ if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, gtk_len,
+ gtk_len, &gd.key_rsc_len,
+ &gd.alg) ||
+ wpa_supplicant_install_mlo_gtk(sm, link_id, &gd, key_rsc, 0)) {
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: Failed to install GTK for MLO Link ID %u",
+ link_id);
+ ret = -1;
+ goto out;
+ }
+
+out:
+ forced_memzero(&gd, sizeof(gd));
+ return ret;
+}
+
+
+static int wpa_supplicant_pairwise_mlo_gtk(struct wpa_sm *sm,
+ const struct wpa_eapol_key *key,
+ struct wpa_eapol_ie_parse *ie,
+ int key_info)
+{
+ u8 i;
+
+ for (i = 0; i < MAX_NUM_MLO_LINKS; i++) {
+ if (!(sm->mlo.setup_links & BIT(i)))
+ continue;
+
+ if (!ie->mlo_gtk[i]) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
+ "MLO RSN: GTK not found for link ID %u", i);
+ return -1;
+ }
+
+ if (wpa_supplicant_mlo_gtk(sm, i, ie->mlo_gtk[i],
+ ie->mlo_gtk_len[i], key_info))
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
const struct wpa_eapol_key *key,
const u8 *gtk, size_t gtk_len,
@@ -1438,6 +1577,185 @@ static int wpa_supplicant_install_bigtk(struct wpa_sm *sm,
return 0;
}
+static int wpa_supplicant_install_mlo_igtk(struct wpa_sm *sm, u8 link_id,
+ const struct rsn_mlo_igtk_kde *igtk,
+ int wnm_sleep)
+{
+ size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
+ u16 keyidx = WPA_GET_LE16(igtk->keyid);
+ char title[100];
+ int ret;
+
+ /* Detect possible key reinstallation */
+ if ((sm->mlo.links[link_id].igtk.igtk_len == len &&
+ os_memcmp(sm->mlo.links[link_id].igtk.igtk, igtk->igtk,
+ sm->mlo.links[link_id].igtk.igtk_len) == 0) ||
+ (sm->mlo.links[link_id].igtk_wnm_sleep.igtk_len == len &&
+ os_memcmp(sm->mlo.links[link_id].igtk_wnm_sleep.igtk, igtk->igtk,
+ sm->mlo.links[link_id].igtk_wnm_sleep.igtk_len) == 0)) {
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: Not reinstalling already in-use IGTK to the driver (link_id=%d keyidx=%d)",
+ link_id, keyidx);
+ return 0;
+ }
+
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: MLO Link %u IGTK keyid %d pn " COMPACT_MACSTR,
+ link_id, keyidx, MAC2STR(igtk->pn));
+ ret = os_snprintf(title, sizeof(title), "RSN: MLO Link %u IGTK",
+ link_id);
+ if (!os_snprintf_error(sizeof(title), ret))
+ wpa_hexdump_key(MSG_DEBUG, title, igtk->igtk, len);
+ if (keyidx > 4095) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "RSN: Invalid MLO Link %d IGTK KeyID %d", link_id,
+ keyidx);
+ return -1;
+ }
+ if (wpa_sm_set_key(sm, link_id,
+ wpa_cipher_to_alg(sm->mgmt_group_cipher),
+ broadcast_ether_addr, keyidx, 0, igtk->pn,
+ sizeof(igtk->pn), igtk->igtk, len,
+ KEY_FLAG_GROUP_RX) < 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "RSN: Failed to configure MLO Link %d IGTK to the driver",
+ link_id);
+ return -1;
+ }
+
+ if (wnm_sleep) {
+ sm->mlo.links[link_id].igtk_wnm_sleep.igtk_len = len;
+ os_memcpy(sm->mlo.links[link_id].igtk_wnm_sleep.igtk,
+ igtk->igtk,
+ sm->mlo.links[link_id].igtk_wnm_sleep.igtk_len);
+ } else {
+ sm->mlo.links[link_id].igtk.igtk_len = len;
+ os_memcpy(sm->mlo.links[link_id].igtk.igtk, igtk->igtk,
+ sm->mlo.links[link_id].igtk.igtk_len);
+ }
+
+ return 0;
+}
+
+
+static int
+wpa_supplicant_install_mlo_bigtk(struct wpa_sm *sm, u8 link_id,
+ const struct rsn_mlo_bigtk_kde *bigtk,
+ int wnm_sleep)
+{
+ size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
+ u16 keyidx = WPA_GET_LE16(bigtk->keyid);
+ char title[100];
+ int ret;
+
+ /* Detect possible key reinstallation */
+ if ((sm->mlo.links[link_id].bigtk.bigtk_len == len &&
+ os_memcmp(sm->mlo.links[link_id].bigtk.bigtk, bigtk->bigtk,
+ sm->mlo.links[link_id].bigtk.bigtk_len) == 0) ||
+ (sm->mlo.links[link_id].bigtk_wnm_sleep.bigtk_len == len &&
+ os_memcmp(sm->mlo.links[link_id].bigtk_wnm_sleep.bigtk,
+ bigtk->bigtk,
+ sm->mlo.links[link_id].bigtk_wnm_sleep.bigtk_len)
+ == 0)) {
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: Not reinstalling already in-use BIGTK to the driver (link_id=%d keyidx=%d)",
+ link_id, keyidx);
+ return 0;
+ }
+
+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ "RSN: MLO Link %u BIGTK keyid %d pn " COMPACT_MACSTR,
+ link_id, keyidx, MAC2STR(bigtk->pn));
+ ret = os_snprintf(title, sizeof(title), "RSN: MLO Link %u BIGTK",
+ link_id);
+ if (!os_snprintf_error(sizeof(title), ret))
+ wpa_hexdump_key(MSG_DEBUG, title, bigtk->bigtk, len);
+ if (keyidx < 6 || keyidx > 7) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "WPA: Invalid MLO Link %d BIGTK KeyID %d", link_id,
+ keyidx);
+ return -1;
+ }
+ if (wpa_sm_set_key(sm, link_id,
+ wpa_cipher_to_alg(sm->mgmt_group_cipher),
+ broadcast_ether_addr, keyidx, 0, bigtk->pn,
+ sizeof(bigtk->pn), bigtk->bigtk, len,
+ KEY_FLAG_GROUP_RX) < 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "RSN: Failed to configure MLO Link %d BIGTK to the driver",
+ link_id);
+ return -1;
+ }
+
+ if (wnm_sleep) {
+ sm->mlo.links[link_id].bigtk_wnm_sleep.bigtk_len = len;
+ os_memcpy(sm->mlo.links[link_id].bigtk_wnm_sleep.bigtk,
+ bigtk->bigtk,
+ sm->mlo.links[link_id].bigtk_wnm_sleep.bigtk_len);
+ } else {
+ sm->mlo.links[link_id].bigtk.bigtk_len = len;
+ os_memcpy(sm->mlo.links[link_id].bigtk.bigtk, bigtk->bigtk,
+ sm->mlo.links[link_id].bigtk.bigtk_len);
+ }
+
+ return 0;
+}
+
+
+static int _mlo_ieee80211w_set_keys(struct wpa_sm *sm, u8 link_id,
+ struct wpa_eapol_ie_parse *ie)
+{
+ size_t len;
+
+ if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
+ return 0;
+
+ if (ie->mlo_igtk[link_id]) {
+ const struct rsn_mlo_igtk_kde *igtk;
+
+ len = wpa_cipher_key_len(sm->mgmt_group_cipher);
+ if (ie->mlo_igtk_len[link_id] !=
+ (RSN_MLO_IGTK_KDE_PREFIX_LENGTH + len))
+ return -1;
+
+ igtk = (const struct rsn_mlo_igtk_kde *) ie->mlo_igtk[link_id];
+ if (wpa_supplicant_install_mlo_igtk(sm, link_id, igtk, 0) < 0)
+ return -1;
+ }
+
+ if (ie->mlo_bigtk[link_id] && sm->beacon_prot) {
+ const struct rsn_mlo_bigtk_kde *bigtk;
+
+ len = wpa_cipher_key_len(sm->mgmt_group_cipher);
+ if (ie->mlo_bigtk_len[link_id] !=
+ (RSN_MLO_BIGTK_KDE_PREFIX_LENGTH + len))
+ return -1;
+
+ bigtk = (const struct rsn_mlo_bigtk_kde *) ie->mlo_bigtk[link_id];
+ if (wpa_supplicant_install_mlo_bigtk(sm, link_id, bigtk, 0) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int mlo_ieee80211w_set_keys(struct wpa_sm *sm,
+ struct wpa_eapol_ie_parse *ie)
+{
+ u8 i;
+
+ for (i = 0; i < MAX_NUM_MLO_LINKS; i++) {
+ if (!(sm->mlo.setup_links & BIT(i)))
+ continue;
+
+ if (_mlo_ieee80211w_set_keys(sm, i, ie))
+ return -1;
+ }
+
+ return 0;
+}
+
static int ieee80211w_set_keys(struct wpa_sm *sm,
struct wpa_eapol_ie_parse *ie)
@@ -1799,6 +2117,130 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
}
+static void wpa_supplicant_process_mlo_3_of_4(struct wpa_sm *sm,
+ const struct wpa_eapol_key *key,
+ u16 ver, const u8 *key_data,
+ size_t key_data_len)
+{
+ u16 key_info, keylen;
+ struct wpa_eapol_ie_parse ie;
+ int res;
+
+ wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
+ wpa_dbg(sm->ctx->msg_ctx, MSG_INFO, "RSN MLO: RX message 3 of 4-Way "
+ "Handshake from " MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);
+
+ key_info = WPA_GET_BE16(key->key_info);
+
+ wpa_hexdump(MSG_DEBUG, "RSN MLO: IE KeyData", key_data, key_data_len);
+ if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
+ goto failed;
+
+ if (!ie.valid_mlo_gtks) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "MLO RSN: No GTK KDE included in EAPOL-Key msg 3/4");
+ goto failed;
+ }
+ if ((key_info &
+ (WPA_KEY_INFO_ENCR_KEY_DATA | WPA_KEY_INFO_INSTALL |
+ WPA_KEY_INFO_SECURE)) !=
+ (WPA_KEY_INFO_ENCR_KEY_DATA | WPA_KEY_INFO_INSTALL |
+ WPA_KEY_INFO_SECURE)) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "RSN MLO: Invalid key info in EAPOL-Key msg 3/4");
+ goto failed;
+ }
+
+#ifdef CONFIG_IEEE80211R
+ if (wpa_key_mgmt_ft(sm->key_mgmt) &&
+ wpa_supplicant_validate_ie_ft(sm, sm->bssid, &ie) < 0)
+ goto failed;
+#endif /* CONFIG_IEEE80211R */
+
+ if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "RSN MLO: ANonce from message 1 of 4-Way Handshake "
+ "differs from 3 of 4-Way Handshake - drop packet (src="
+ MACSTR ")", MAC2STR(sm->bssid));
+ goto failed;
+ }
+
+ keylen = WPA_GET_BE16(key->key_length);
+ if (keylen != wpa_cipher_key_len(sm->pairwise_cipher)) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "RSN MLO: Invalid %s key length %d (src=" MACSTR")",
+ wpa_cipher_txt(sm->pairwise_cipher), keylen,
+ MAC2STR(sm->bssid));
+ goto failed;
+ }
+
+ if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
+ &sm->ptk) < 0)
+ goto failed;
+
+ /* SNonce was successfully used in msg 3/4, so mark it to be renewed
+ * for the next 4-Way Handshake. If msg 3 is received again, the old
+ * SNonce will still be used to avoid changing PTK. */
+ sm->renew_snonce = 1;
+
+
+ if (sm->use_ext_key_id)
+ res = wpa_supplicant_activate_ptk(sm);
+ else
+ res = wpa_supplicant_install_ptk(sm, key, KEY_FLAG_RX_TX);
+ if (res)
+ goto failed;
+
+ wpa_sm_mlme_setprotection(sm, sm->bssid,
+ MLME_SETPROTECTION_PROTECT_TYPE_RX,
+ MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
+ eapol_sm_notify_portValid(sm->eapol, true);
+
+ wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
+
+ if (wpa_supplicant_pairwise_mlo_gtk(sm, key, &ie, key_info) < 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "MLO RSN: Failed to configure MLO GTKs");
+ goto failed;
+ }
+
+ if (mlo_ieee80211w_set_keys(sm, &ie) < 0) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "MLO RSN: Failed to configure IGTK");
+ goto failed;
+ }
+
+ wpa_supplicant_key_neg_complete(sm, sm->bssid,
+ key_info & WPA_KEY_INFO_SECURE);
+ wpa_sm_set_rekey_offload(sm);
+
+ /* Add PMKSA cache entry for Suite B AKMs here since PMKID can be
+ * calculated only after KCK has been derived. Though, do not replace an
+ * existing PMKSA entry after each 4-way handshake (i.e., new KCK/PMKID)
+ * to avoid unnecessary changes of PMKID while continuing to use the
+ * same PMK. */
+ if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt) &&
+ !sm->cur_pmksa) {
+ struct rsn_pmksa_cache_entry *sa;
+
+ sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, NULL,
+ sm->ptk.kck, sm->ptk.kck_len,
+ sm->bssid, sm->own_addr,
+ sm->network_ctx, sm->key_mgmt, NULL);
+ if (!sm->cur_pmksa)
+ sm->cur_pmksa = sa;
+ }
+
+ if (ie.transition_disable)
+ wpa_sm_transition_disable(sm, ie.transition_disable[0]);
+ sm->msg_3_of_4_ok = 1;
+ return;
+
+failed:
+ wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
+}
+
+
static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
const struct wpa_eapol_key *key,
u16 ver, const u8 *key_data,
@@ -2861,8 +3303,13 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
if (key_info & (WPA_KEY_INFO_MIC |
WPA_KEY_INFO_ENCR_KEY_DATA)) {
/* 3/4 4-Way Handshake */
- wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
- key_data_len);
+ if (sm->mlo.setup_links)
+ wpa_supplicant_process_mlo_3_of_4(
+ sm, key, ver, key_data, key_data_len);
+ else
+ wpa_supplicant_process_3_of_4(sm, key, ver,
+ key_data,
+ key_data_len);
} else {
/* 1/4 4-Way Handshake */
wpa_supplicant_process_1_of_4(sm, src_addr, key,
@@ -3159,6 +3606,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
{
int clear_keys = 1;
+ int i;
if (sm == NULL)
return;
@@ -3216,6 +3664,16 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
os_memset(&sm->igtk, 0, sizeof(sm->igtk));
os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
sm->tk_set = false;
+ for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+ os_memset(&sm->mlo.links[i].gtk, 0,
+ sizeof(sm->mlo.links[i].gtk));
+ os_memset(&sm->mlo.links[i].gtk_wnm_sleep, 0,
+ sizeof(sm->mlo.links[i].gtk_wnm_sleep));
+ os_memset(&sm->mlo.links[i].igtk, 0,
+ sizeof(sm->mlo.links[i].igtk));
+ os_memset(&sm->mlo.links[i].igtk_wnm_sleep, 0,
+ sizeof(sm->mlo.links[i].igtk_wnm_sleep));
+ }
}
#ifdef CONFIG_TDLS
@@ -4063,6 +4521,8 @@ struct rsn_pmksa_cache_entry * wpa_sm_pmksa_cache_get(struct wpa_sm *sm,
void wpa_sm_drop_sa(struct wpa_sm *sm)
{
+ int i;
+
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
sm->ptk_set = 0;
sm->tptk_set = 0;
@@ -4075,6 +4535,16 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
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));
+ for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+ os_memset(&sm->mlo.links[i].gtk, 0,
+ sizeof(sm->mlo.links[i].gtk));
+ os_memset(&sm->mlo.links[i].gtk_wnm_sleep, 0,
+ sizeof(sm->mlo.links[i].gtk_wnm_sleep));
+ os_memset(&sm->mlo.links[i].igtk, 0,
+ sizeof(sm->mlo.links[i].igtk));
+ os_memset(&sm->mlo.links[i].igtk_wnm_sleep, 0,
+ sizeof(sm->mlo.links[i].igtk_wnm_sleep));
+ }
#ifdef CONFIG_IEEE80211R
os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
sm->xxkey_len = 0;
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 28a2509..45717f8 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -24,6 +24,12 @@ struct wpa_sm_link {
u8 bssid[ETH_ALEN];
u8 *ap_rsne, *ap_rsnxe;
size_t ap_rsne_len, ap_rsnxe_len;
+ struct wpa_gtk gtk;
+ struct wpa_gtk gtk_wnm_sleep;
+ struct wpa_igtk igtk;
+ struct wpa_igtk igtk_wnm_sleep;
+ struct wpa_bigtk bigtk;
+ struct wpa_bigtk bigtk_wnm_sleep;
} links[MAX_NUM_MLD_LINKS];
struct wpa_sm_mlo {
--
2.7.4
More information about the Hostap
mailing list