developer | 78848c6 | 2023-04-06 13:44:00 +0800 | [diff] [blame^] | 1 | From: Felix Fietkau <nbd@nbd.name> |
| 2 | Date: Wed, 22 Mar 2023 10:17:49 +0100 |
| 3 | Subject: [PATCH] wifi: mt76: ignore key disable commands |
| 4 | |
| 5 | This helps avoid cleartext leakage of already queued or powersave buffered |
| 6 | packets, when a reassoc triggers the key deletion. |
| 7 | |
| 8 | Cc: stable@vger.kernel.org |
| 9 | Signed-off-by: Felix Fietkau <nbd@nbd.name> |
| 10 | --- |
| 11 | |
| 12 | --- a/mt7603/main.c |
| 13 | +++ b/mt7603/main.c |
| 14 | @@ -512,15 +512,15 @@ mt7603_set_key(struct ieee80211_hw *hw, |
| 15 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) |
| 16 | return -EOPNOTSUPP; |
| 17 | |
| 18 | - if (cmd == SET_KEY) { |
| 19 | - key->hw_key_idx = wcid->idx; |
| 20 | - wcid->hw_key_idx = idx; |
| 21 | - } else { |
| 22 | + if (cmd != SET_KEY) { |
| 23 | if (idx == wcid->hw_key_idx) |
| 24 | wcid->hw_key_idx = -1; |
| 25 | |
| 26 | - key = NULL; |
| 27 | + return 0; |
| 28 | } |
| 29 | + |
| 30 | + key->hw_key_idx = wcid->idx; |
| 31 | + wcid->hw_key_idx = idx; |
| 32 | mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 33 | |
| 34 | return mt7603_wtbl_set_key(dev, wcid->idx, key); |
| 35 | --- a/mt7615/mac.c |
| 36 | +++ b/mt7615/mac.c |
| 37 | @@ -1193,8 +1193,7 @@ EXPORT_SYMBOL_GPL(mt7615_mac_enable_rtsc |
| 38 | static int |
| 39 | mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid, |
| 40 | struct ieee80211_key_conf *key, |
| 41 | - enum mt76_cipher_type cipher, u16 cipher_mask, |
| 42 | - enum set_key_cmd cmd) |
| 43 | + enum mt76_cipher_type cipher, u16 cipher_mask) |
| 44 | { |
| 45 | u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx) + 30 * 4; |
| 46 | u8 data[32] = {}; |
| 47 | @@ -1203,27 +1202,18 @@ mt7615_mac_wtbl_update_key(struct mt7615 |
| 48 | return -EINVAL; |
| 49 | |
| 50 | mt76_rr_copy(dev, addr, data, sizeof(data)); |
| 51 | - if (cmd == SET_KEY) { |
| 52 | - if (cipher == MT_CIPHER_TKIP) { |
| 53 | - /* Rx/Tx MIC keys are swapped */ |
| 54 | - memcpy(data, key->key, 16); |
| 55 | - memcpy(data + 16, key->key + 24, 8); |
| 56 | - memcpy(data + 24, key->key + 16, 8); |
| 57 | - } else { |
| 58 | - if (cipher_mask == BIT(cipher)) |
| 59 | - memcpy(data, key->key, key->keylen); |
| 60 | - else if (cipher != MT_CIPHER_BIP_CMAC_128) |
| 61 | - memcpy(data, key->key, 16); |
| 62 | - if (cipher == MT_CIPHER_BIP_CMAC_128) |
| 63 | - memcpy(data + 16, key->key, 16); |
| 64 | - } |
| 65 | + if (cipher == MT_CIPHER_TKIP) { |
| 66 | + /* Rx/Tx MIC keys are swapped */ |
| 67 | + memcpy(data, key->key, 16); |
| 68 | + memcpy(data + 16, key->key + 24, 8); |
| 69 | + memcpy(data + 24, key->key + 16, 8); |
| 70 | } else { |
| 71 | + if (cipher_mask == BIT(cipher)) |
| 72 | + memcpy(data, key->key, key->keylen); |
| 73 | + else if (cipher != MT_CIPHER_BIP_CMAC_128) |
| 74 | + memcpy(data, key->key, 16); |
| 75 | if (cipher == MT_CIPHER_BIP_CMAC_128) |
| 76 | - memset(data + 16, 0, 16); |
| 77 | - else if (cipher_mask) |
| 78 | - memset(data, 0, 16); |
| 79 | - if (!cipher_mask) |
| 80 | - memset(data, 0, sizeof(data)); |
| 81 | + memcpy(data + 16, key->key, 16); |
| 82 | } |
| 83 | |
| 84 | mt76_wr_copy(dev, addr, data, sizeof(data)); |
| 85 | @@ -1234,7 +1224,7 @@ mt7615_mac_wtbl_update_key(struct mt7615 |
| 86 | static int |
| 87 | mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid, |
| 88 | enum mt76_cipher_type cipher, u16 cipher_mask, |
| 89 | - int keyidx, enum set_key_cmd cmd) |
| 90 | + int keyidx) |
| 91 | { |
| 92 | u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx), w0, w1; |
| 93 | |
| 94 | @@ -1253,9 +1243,7 @@ mt7615_mac_wtbl_update_pk(struct mt7615_ |
| 95 | else |
| 96 | w0 &= ~MT_WTBL_W0_RX_IK_VALID; |
| 97 | |
| 98 | - if (cmd == SET_KEY && |
| 99 | - (cipher != MT_CIPHER_BIP_CMAC_128 || |
| 100 | - cipher_mask == BIT(cipher))) { |
| 101 | + if (cipher != MT_CIPHER_BIP_CMAC_128 || cipher_mask == BIT(cipher)) { |
| 102 | w0 &= ~MT_WTBL_W0_KEY_IDX; |
| 103 | w0 |= FIELD_PREP(MT_WTBL_W0_KEY_IDX, keyidx); |
| 104 | } |
| 105 | @@ -1272,19 +1260,10 @@ mt7615_mac_wtbl_update_pk(struct mt7615_ |
| 106 | |
| 107 | static void |
| 108 | mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid, |
| 109 | - enum mt76_cipher_type cipher, u16 cipher_mask, |
| 110 | - enum set_key_cmd cmd) |
| 111 | + enum mt76_cipher_type cipher, u16 cipher_mask) |
| 112 | { |
| 113 | u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx); |
| 114 | |
| 115 | - if (!cipher_mask) { |
| 116 | - mt76_clear(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE); |
| 117 | - return; |
| 118 | - } |
| 119 | - |
| 120 | - if (cmd != SET_KEY) |
| 121 | - return; |
| 122 | - |
| 123 | if (cipher == MT_CIPHER_BIP_CMAC_128 && |
| 124 | cipher_mask & ~BIT(MT_CIPHER_BIP_CMAC_128)) |
| 125 | return; |
| 126 | @@ -1295,8 +1274,7 @@ mt7615_mac_wtbl_update_cipher(struct mt7 |
| 127 | |
| 128 | int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, |
| 129 | struct mt76_wcid *wcid, |
| 130 | - struct ieee80211_key_conf *key, |
| 131 | - enum set_key_cmd cmd) |
| 132 | + struct ieee80211_key_conf *key) |
| 133 | { |
| 134 | enum mt76_cipher_type cipher; |
| 135 | u16 cipher_mask = wcid->cipher; |
| 136 | @@ -1306,19 +1284,14 @@ int __mt7615_mac_wtbl_set_key(struct mt7 |
| 137 | if (cipher == MT_CIPHER_NONE) |
| 138 | return -EOPNOTSUPP; |
| 139 | |
| 140 | - if (cmd == SET_KEY) |
| 141 | - cipher_mask |= BIT(cipher); |
| 142 | - else |
| 143 | - cipher_mask &= ~BIT(cipher); |
| 144 | - |
| 145 | - mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cipher_mask, cmd); |
| 146 | - err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cipher_mask, |
| 147 | - cmd); |
| 148 | + cipher_mask |= BIT(cipher); |
| 149 | + mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cipher_mask); |
| 150 | + err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cipher_mask); |
| 151 | if (err < 0) |
| 152 | return err; |
| 153 | |
| 154 | err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, cipher_mask, |
| 155 | - key->keyidx, cmd); |
| 156 | + key->keyidx); |
| 157 | if (err < 0) |
| 158 | return err; |
| 159 | |
| 160 | @@ -1329,13 +1302,12 @@ int __mt7615_mac_wtbl_set_key(struct mt7 |
| 161 | |
| 162 | int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, |
| 163 | struct mt76_wcid *wcid, |
| 164 | - struct ieee80211_key_conf *key, |
| 165 | - enum set_key_cmd cmd) |
| 166 | + struct ieee80211_key_conf *key) |
| 167 | { |
| 168 | int err; |
| 169 | |
| 170 | spin_lock_bh(&dev->mt76.lock); |
| 171 | - err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd); |
| 172 | + err = __mt7615_mac_wtbl_set_key(dev, wcid, key); |
| 173 | spin_unlock_bh(&dev->mt76.lock); |
| 174 | |
| 175 | return err; |
| 176 | --- a/mt7615/main.c |
| 177 | +++ b/mt7615/main.c |
| 178 | @@ -391,18 +391,17 @@ static int mt7615_set_key(struct ieee802 |
| 179 | |
| 180 | if (cmd == SET_KEY) |
| 181 | *wcid_keyidx = idx; |
| 182 | - else if (idx == *wcid_keyidx) |
| 183 | - *wcid_keyidx = -1; |
| 184 | - else |
| 185 | + else { |
| 186 | + if (idx == *wcid_keyidx) |
| 187 | + *wcid_keyidx = -1; |
| 188 | goto out; |
| 189 | + } |
| 190 | |
| 191 | - mt76_wcid_key_setup(&dev->mt76, wcid, |
| 192 | - cmd == SET_KEY ? key : NULL); |
| 193 | - |
| 194 | + mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 195 | if (mt76_is_mmio(&dev->mt76)) |
| 196 | - err = mt7615_mac_wtbl_set_key(dev, wcid, key, cmd); |
| 197 | + err = mt7615_mac_wtbl_set_key(dev, wcid, key); |
| 198 | else |
| 199 | - err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd); |
| 200 | + err = __mt7615_mac_wtbl_set_key(dev, wcid, key); |
| 201 | |
| 202 | out: |
| 203 | mt7615_mutex_release(dev); |
| 204 | --- a/mt7615/mt7615.h |
| 205 | +++ b/mt7615/mt7615.h |
| 206 | @@ -491,11 +491,9 @@ int mt7615_mac_write_txwi(struct mt7615_ |
| 207 | void mt7615_mac_set_timing(struct mt7615_phy *phy); |
| 208 | int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, |
| 209 | struct mt76_wcid *wcid, |
| 210 | - struct ieee80211_key_conf *key, |
| 211 | - enum set_key_cmd cmd); |
| 212 | + struct ieee80211_key_conf *key); |
| 213 | int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, struct mt76_wcid *wcid, |
| 214 | - struct ieee80211_key_conf *key, |
| 215 | - enum set_key_cmd cmd); |
| 216 | + struct ieee80211_key_conf *key); |
| 217 | void mt7615_mac_reset_work(struct work_struct *work); |
| 218 | u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid); |
| 219 | |
| 220 | --- a/mt76x02_util.c |
| 221 | +++ b/mt76x02_util.c |
| 222 | @@ -454,20 +454,20 @@ int mt76x02_set_key(struct ieee80211_hw |
| 223 | msta = sta ? (struct mt76x02_sta *)sta->drv_priv : NULL; |
| 224 | wcid = msta ? &msta->wcid : &mvif->group_wcid; |
| 225 | |
| 226 | - if (cmd == SET_KEY) { |
| 227 | - key->hw_key_idx = wcid->idx; |
| 228 | - wcid->hw_key_idx = idx; |
| 229 | - if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) { |
| 230 | - key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; |
| 231 | - wcid->sw_iv = true; |
| 232 | - } |
| 233 | - } else { |
| 234 | + if (cmd != SET_KEY) { |
| 235 | if (idx == wcid->hw_key_idx) { |
| 236 | wcid->hw_key_idx = -1; |
| 237 | wcid->sw_iv = false; |
| 238 | } |
| 239 | |
| 240 | - key = NULL; |
| 241 | + return 0; |
| 242 | + } |
| 243 | + |
| 244 | + key->hw_key_idx = wcid->idx; |
| 245 | + wcid->hw_key_idx = idx; |
| 246 | + if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) { |
| 247 | + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; |
| 248 | + wcid->sw_iv = true; |
| 249 | } |
| 250 | mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 251 | |
| 252 | --- a/mt7915/main.c |
| 253 | +++ b/mt7915/main.c |
| 254 | @@ -410,16 +410,15 @@ static int mt7915_set_key(struct ieee802 |
| 255 | mt7915_mcu_add_bss_info(phy, vif, true); |
| 256 | } |
| 257 | |
| 258 | - if (cmd == SET_KEY) |
| 259 | + if (cmd == SET_KEY) { |
| 260 | *wcid_keyidx = idx; |
| 261 | - else if (idx == *wcid_keyidx) |
| 262 | - *wcid_keyidx = -1; |
| 263 | - else |
| 264 | + } else { |
| 265 | + if (idx == *wcid_keyidx) |
| 266 | + *wcid_keyidx = -1; |
| 267 | goto out; |
| 268 | + } |
| 269 | |
| 270 | - mt76_wcid_key_setup(&dev->mt76, wcid, |
| 271 | - cmd == SET_KEY ? key : NULL); |
| 272 | - |
| 273 | + mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 274 | err = mt76_connac_mcu_add_key(&dev->mt76, vif, &msta->bip, |
| 275 | key, MCU_EXT_CMD(STA_REC_UPDATE), |
| 276 | &msta->wcid, cmd); |
| 277 | --- a/mt7921/main.c |
| 278 | +++ b/mt7921/main.c |
| 279 | @@ -569,16 +569,15 @@ static int mt7921_set_key(struct ieee802 |
| 280 | |
| 281 | mt7921_mutex_acquire(dev); |
| 282 | |
| 283 | - if (cmd == SET_KEY) |
| 284 | + if (cmd == SET_KEY) { |
| 285 | *wcid_keyidx = idx; |
| 286 | - else if (idx == *wcid_keyidx) |
| 287 | - *wcid_keyidx = -1; |
| 288 | - else |
| 289 | + } else { |
| 290 | + if (idx == *wcid_keyidx) |
| 291 | + *wcid_keyidx = -1; |
| 292 | goto out; |
| 293 | + } |
| 294 | |
| 295 | - mt76_wcid_key_setup(&dev->mt76, wcid, |
| 296 | - cmd == SET_KEY ? key : NULL); |
| 297 | - |
| 298 | + mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 299 | err = mt76_connac_mcu_add_key(&dev->mt76, vif, &msta->bip, |
| 300 | key, MCU_UNI_CMD(STA_REC_UPDATE), |
| 301 | &msta->wcid, cmd); |
| 302 | --- a/mt7996/main.c |
| 303 | +++ b/mt7996/main.c |
| 304 | @@ -351,16 +351,15 @@ static int mt7996_set_key(struct ieee802 |
| 305 | mt7996_mcu_add_bss_info(phy, vif, true); |
| 306 | } |
| 307 | |
| 308 | - if (cmd == SET_KEY) |
| 309 | + if (cmd == SET_KEY) { |
| 310 | *wcid_keyidx = idx; |
| 311 | - else if (idx == *wcid_keyidx) |
| 312 | - *wcid_keyidx = -1; |
| 313 | - else |
| 314 | + } else { |
| 315 | + if (idx == *wcid_keyidx) |
| 316 | + *wcid_keyidx = -1; |
| 317 | goto out; |
| 318 | + } |
| 319 | |
| 320 | - mt76_wcid_key_setup(&dev->mt76, wcid, |
| 321 | - cmd == SET_KEY ? key : NULL); |
| 322 | - |
| 323 | + mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 324 | err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip, |
| 325 | key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE), |
| 326 | &msta->wcid, cmd); |