wifi: iwlwifi: mvm/mld: correctly retrieve the keyidx from the beacon

key->icv_len already includes the pn length and the keyidx length.
In fact it is the size of the MMIE, so subtracting it from the overall
length will actually bring us to the beggining of the MMIE and not of
the keyidx inside it.
Also, we also need to consider a 16 byte long MIC.

Fix the code to correctly retrieve the keyidx.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250821204455.e0aea411cd2a.I4220348147541a1478b02389475426047ecf84bc@changeid
This commit is contained in:
Miri Korenblit 2025-08-21 20:47:17 +03:00
parent 8925c7876c
commit 6a1adca41f
2 changed files with 15 additions and 7 deletions

View File

@ -1611,8 +1611,6 @@ iwl_mld_rx_with_sta(struct iwl_mld *mld, struct ieee80211_hdr *hdr,
return sta;
}
#define KEY_IDX_LEN 2
static int iwl_mld_rx_mgmt_prot(struct ieee80211_sta *sta,
struct ieee80211_hdr *hdr,
struct ieee80211_rx_status *rx_status,
@ -1626,6 +1624,7 @@ static int iwl_mld_rx_mgmt_prot(struct ieee80211_sta *sta,
u8 keyidx;
struct ieee80211_key_conf *key;
const u8 *frame = (void *)hdr;
const u8 *mmie;
u8 link_id;
if ((mpdu_status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
@ -1674,11 +1673,15 @@ static int iwl_mld_rx_mgmt_prot(struct ieee80211_sta *sta,
goto report;
}
if (mpdu_len < key->icv_len + IEEE80211_GMAC_PN_LEN + KEY_IDX_LEN)
/* get the real key ID */
if (mpdu_len < key->icv_len)
goto report;
/* get the real key ID */
keyidx = frame[mpdu_len - key->icv_len - IEEE80211_GMAC_PN_LEN - KEY_IDX_LEN];
mmie = frame + (mpdu_len - key->icv_len);
/* the position of the key_id in ieee80211_mmie_16 is the same */
keyidx = le16_to_cpu(((const struct ieee80211_mmie *) mmie)->key_id);
/* and if that's the other key, look it up */
if (keyidx != key->keyidx) {
/* shouldn't happen since firmware checked, but be safe

View File

@ -332,6 +332,7 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
struct ieee80211_key_conf *key;
u32 len = le16_to_cpu(desc->mpdu_len);
const u8 *frame = (void *)hdr;
const u8 *mmie;
if ((status & IWL_RX_MPDU_STATUS_SEC_MASK) == IWL_RX_MPDU_STATUS_SEC_NONE)
return 0;
@ -375,11 +376,15 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
goto report;
}
if (len < key->icv_len + IEEE80211_GMAC_PN_LEN + 2)
if (len < key->icv_len)
goto report;
/* get the real key ID */
keyid = frame[len - key->icv_len - IEEE80211_GMAC_PN_LEN - 2];
mmie = frame + (len - key->icv_len);
/* the position of the key_id in ieee80211_mmie_16 is the same */
keyid = le16_to_cpu(((const struct ieee80211_mmie *) mmie)->key_id);
/* and if that's the other key, look it up */
if (keyid != key->keyidx) {
/*