Skip to content

Commit e6db67f

Browse files
nbd168Kalle Valo
authored andcommitted
wifi: mt76: ignore key disable commands
This helps avoid cleartext leakage of already queued or powersave buffered packets, when a reassoc triggers the key deletion. Cc: [email protected] Signed-off-by: Felix Fietkau <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent cf5fa3c commit e6db67f

File tree

8 files changed

+62
-96
lines changed

8 files changed

+62
-96
lines changed

drivers/net/wireless/mediatek/mt76/mt7603/main.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -512,15 +512,15 @@ mt7603_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
512512
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
513513
return -EOPNOTSUPP;
514514

515-
if (cmd == SET_KEY) {
516-
key->hw_key_idx = wcid->idx;
517-
wcid->hw_key_idx = idx;
518-
} else {
515+
if (cmd != SET_KEY) {
519516
if (idx == wcid->hw_key_idx)
520517
wcid->hw_key_idx = -1;
521518

522-
key = NULL;
519+
return 0;
523520
}
521+
522+
key->hw_key_idx = wcid->idx;
523+
wcid->hw_key_idx = idx;
524524
mt76_wcid_key_setup(&dev->mt76, wcid, key);
525525

526526
return mt7603_wtbl_set_key(dev, wcid->idx, key);

drivers/net/wireless/mediatek/mt76/mt7615/mac.c

Lines changed: 21 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,8 +1193,7 @@ EXPORT_SYMBOL_GPL(mt7615_mac_enable_rtscts);
11931193
static int
11941194
mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
11951195
struct ieee80211_key_conf *key,
1196-
enum mt76_cipher_type cipher, u16 cipher_mask,
1197-
enum set_key_cmd cmd)
1196+
enum mt76_cipher_type cipher, u16 cipher_mask)
11981197
{
11991198
u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx) + 30 * 4;
12001199
u8 data[32] = {};
@@ -1203,27 +1202,18 @@ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
12031202
return -EINVAL;
12041203

12051204
mt76_rr_copy(dev, addr, data, sizeof(data));
1206-
if (cmd == SET_KEY) {
1207-
if (cipher == MT_CIPHER_TKIP) {
1208-
/* Rx/Tx MIC keys are swapped */
1209-
memcpy(data, key->key, 16);
1210-
memcpy(data + 16, key->key + 24, 8);
1211-
memcpy(data + 24, key->key + 16, 8);
1212-
} else {
1213-
if (cipher_mask == BIT(cipher))
1214-
memcpy(data, key->key, key->keylen);
1215-
else if (cipher != MT_CIPHER_BIP_CMAC_128)
1216-
memcpy(data, key->key, 16);
1217-
if (cipher == MT_CIPHER_BIP_CMAC_128)
1218-
memcpy(data + 16, key->key, 16);
1219-
}
1205+
if (cipher == MT_CIPHER_TKIP) {
1206+
/* Rx/Tx MIC keys are swapped */
1207+
memcpy(data, key->key, 16);
1208+
memcpy(data + 16, key->key + 24, 8);
1209+
memcpy(data + 24, key->key + 16, 8);
12201210
} else {
1211+
if (cipher_mask == BIT(cipher))
1212+
memcpy(data, key->key, key->keylen);
1213+
else if (cipher != MT_CIPHER_BIP_CMAC_128)
1214+
memcpy(data, key->key, 16);
12211215
if (cipher == MT_CIPHER_BIP_CMAC_128)
1222-
memset(data + 16, 0, 16);
1223-
else if (cipher_mask)
1224-
memset(data, 0, 16);
1225-
if (!cipher_mask)
1226-
memset(data, 0, sizeof(data));
1216+
memcpy(data + 16, key->key, 16);
12271217
}
12281218

12291219
mt76_wr_copy(dev, addr, data, sizeof(data));
@@ -1234,7 +1224,7 @@ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
12341224
static int
12351225
mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
12361226
enum mt76_cipher_type cipher, u16 cipher_mask,
1237-
int keyidx, enum set_key_cmd cmd)
1227+
int keyidx)
12381228
{
12391229
u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx), w0, w1;
12401230

@@ -1253,9 +1243,7 @@ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
12531243
else
12541244
w0 &= ~MT_WTBL_W0_RX_IK_VALID;
12551245

1256-
if (cmd == SET_KEY &&
1257-
(cipher != MT_CIPHER_BIP_CMAC_128 ||
1258-
cipher_mask == BIT(cipher))) {
1246+
if (cipher != MT_CIPHER_BIP_CMAC_128 || cipher_mask == BIT(cipher)) {
12591247
w0 &= ~MT_WTBL_W0_KEY_IDX;
12601248
w0 |= FIELD_PREP(MT_WTBL_W0_KEY_IDX, keyidx);
12611249
}
@@ -1272,19 +1260,10 @@ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
12721260

12731261
static void
12741262
mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid,
1275-
enum mt76_cipher_type cipher, u16 cipher_mask,
1276-
enum set_key_cmd cmd)
1263+
enum mt76_cipher_type cipher, u16 cipher_mask)
12771264
{
12781265
u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx);
12791266

1280-
if (!cipher_mask) {
1281-
mt76_clear(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE);
1282-
return;
1283-
}
1284-
1285-
if (cmd != SET_KEY)
1286-
return;
1287-
12881267
if (cipher == MT_CIPHER_BIP_CMAC_128 &&
12891268
cipher_mask & ~BIT(MT_CIPHER_BIP_CMAC_128))
12901269
return;
@@ -1295,8 +1274,7 @@ mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid,
12951274

12961275
int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
12971276
struct mt76_wcid *wcid,
1298-
struct ieee80211_key_conf *key,
1299-
enum set_key_cmd cmd)
1277+
struct ieee80211_key_conf *key)
13001278
{
13011279
enum mt76_cipher_type cipher;
13021280
u16 cipher_mask = wcid->cipher;
@@ -1306,19 +1284,14 @@ int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
13061284
if (cipher == MT_CIPHER_NONE)
13071285
return -EOPNOTSUPP;
13081286

1309-
if (cmd == SET_KEY)
1310-
cipher_mask |= BIT(cipher);
1311-
else
1312-
cipher_mask &= ~BIT(cipher);
1313-
1314-
mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cipher_mask, cmd);
1315-
err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cipher_mask,
1316-
cmd);
1287+
cipher_mask |= BIT(cipher);
1288+
mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cipher_mask);
1289+
err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cipher_mask);
13171290
if (err < 0)
13181291
return err;
13191292

13201293
err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, cipher_mask,
1321-
key->keyidx, cmd);
1294+
key->keyidx);
13221295
if (err < 0)
13231296
return err;
13241297

@@ -1329,13 +1302,12 @@ int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
13291302

13301303
int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
13311304
struct mt76_wcid *wcid,
1332-
struct ieee80211_key_conf *key,
1333-
enum set_key_cmd cmd)
1305+
struct ieee80211_key_conf *key)
13341306
{
13351307
int err;
13361308

13371309
spin_lock_bh(&dev->mt76.lock);
1338-
err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
1310+
err = __mt7615_mac_wtbl_set_key(dev, wcid, key);
13391311
spin_unlock_bh(&dev->mt76.lock);
13401312

13411313
return err;

drivers/net/wireless/mediatek/mt76/mt7615/main.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -391,18 +391,17 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
391391

392392
if (cmd == SET_KEY)
393393
*wcid_keyidx = idx;
394-
else if (idx == *wcid_keyidx)
395-
*wcid_keyidx = -1;
396-
else
394+
else {
395+
if (idx == *wcid_keyidx)
396+
*wcid_keyidx = -1;
397397
goto out;
398+
}
398399

399-
mt76_wcid_key_setup(&dev->mt76, wcid,
400-
cmd == SET_KEY ? key : NULL);
401-
400+
mt76_wcid_key_setup(&dev->mt76, wcid, key);
402401
if (mt76_is_mmio(&dev->mt76))
403-
err = mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
402+
err = mt7615_mac_wtbl_set_key(dev, wcid, key);
404403
else
405-
err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
404+
err = __mt7615_mac_wtbl_set_key(dev, wcid, key);
406405

407406
out:
408407
mt7615_mutex_release(dev);

drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,9 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
490490
void mt7615_mac_set_timing(struct mt7615_phy *phy);
491491
int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
492492
struct mt76_wcid *wcid,
493-
struct ieee80211_key_conf *key,
494-
enum set_key_cmd cmd);
493+
struct ieee80211_key_conf *key);
495494
int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
496-
struct ieee80211_key_conf *key,
497-
enum set_key_cmd cmd);
495+
struct ieee80211_key_conf *key);
498496
void mt7615_mac_reset_work(struct work_struct *work);
499497
u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid);
500498

drivers/net/wireless/mediatek/mt76/mt76x02_util.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -454,20 +454,20 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
454454
msta = sta ? (struct mt76x02_sta *)sta->drv_priv : NULL;
455455
wcid = msta ? &msta->wcid : &mvif->group_wcid;
456456

457-
if (cmd == SET_KEY) {
458-
key->hw_key_idx = wcid->idx;
459-
wcid->hw_key_idx = idx;
460-
if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
461-
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
462-
wcid->sw_iv = true;
463-
}
464-
} else {
457+
if (cmd != SET_KEY) {
465458
if (idx == wcid->hw_key_idx) {
466459
wcid->hw_key_idx = -1;
467460
wcid->sw_iv = false;
468461
}
469462

470-
key = NULL;
463+
return 0;
464+
}
465+
466+
key->hw_key_idx = wcid->idx;
467+
wcid->hw_key_idx = idx;
468+
if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
469+
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
470+
wcid->sw_iv = true;
471471
}
472472
mt76_wcid_key_setup(&dev->mt76, wcid, key);
473473

drivers/net/wireless/mediatek/mt76/mt7915/main.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -410,16 +410,15 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
410410
mt7915_mcu_add_bss_info(phy, vif, true);
411411
}
412412

413-
if (cmd == SET_KEY)
413+
if (cmd == SET_KEY) {
414414
*wcid_keyidx = idx;
415-
else if (idx == *wcid_keyidx)
416-
*wcid_keyidx = -1;
417-
else
415+
} else {
416+
if (idx == *wcid_keyidx)
417+
*wcid_keyidx = -1;
418418
goto out;
419+
}
419420

420-
mt76_wcid_key_setup(&dev->mt76, wcid,
421-
cmd == SET_KEY ? key : NULL);
422-
421+
mt76_wcid_key_setup(&dev->mt76, wcid, key);
423422
err = mt76_connac_mcu_add_key(&dev->mt76, vif, &msta->bip,
424423
key, MCU_EXT_CMD(STA_REC_UPDATE),
425424
&msta->wcid, cmd);

drivers/net/wireless/mediatek/mt76/mt7921/main.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -569,16 +569,15 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
569569

570570
mt7921_mutex_acquire(dev);
571571

572-
if (cmd == SET_KEY)
572+
if (cmd == SET_KEY) {
573573
*wcid_keyidx = idx;
574-
else if (idx == *wcid_keyidx)
575-
*wcid_keyidx = -1;
576-
else
574+
} else {
575+
if (idx == *wcid_keyidx)
576+
*wcid_keyidx = -1;
577577
goto out;
578+
}
578579

579-
mt76_wcid_key_setup(&dev->mt76, wcid,
580-
cmd == SET_KEY ? key : NULL);
581-
580+
mt76_wcid_key_setup(&dev->mt76, wcid, key);
582581
err = mt76_connac_mcu_add_key(&dev->mt76, vif, &msta->bip,
583582
key, MCU_UNI_CMD(STA_REC_UPDATE),
584583
&msta->wcid, cmd);

drivers/net/wireless/mediatek/mt76/mt7996/main.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,16 +351,15 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
351351
mt7996_mcu_add_bss_info(phy, vif, true);
352352
}
353353

354-
if (cmd == SET_KEY)
354+
if (cmd == SET_KEY) {
355355
*wcid_keyidx = idx;
356-
else if (idx == *wcid_keyidx)
357-
*wcid_keyidx = -1;
358-
else
356+
} else {
357+
if (idx == *wcid_keyidx)
358+
*wcid_keyidx = -1;
359359
goto out;
360+
}
360361

361-
mt76_wcid_key_setup(&dev->mt76, wcid,
362-
cmd == SET_KEY ? key : NULL);
363-
362+
mt76_wcid_key_setup(&dev->mt76, wcid, key);
364363
err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip,
365364
key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
366365
&msta->wcid, cmd);

0 commit comments

Comments
 (0)