wireless-regdb: add package containing the wireless regulatory database
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / 329-mac80211-don-t-compare-TKIP-TX-MIC-key-in-reinstall.patch
1 From cfbb0d90a7abb289edc91833d0905931f8805f12 Mon Sep 17 00:00:00 2001
2 From: Johannes Berg <johannes.berg@intel.com>
3 Date: Tue, 24 Oct 2017 21:12:13 +0200
4 Subject: [PATCH] mac80211: don't compare TKIP TX MIC key in reinstall prevention
5
6 For the reinstall prevention, the code I had added compares the
7 whole key. It turns out though that iwlwifi firmware doesn't
8 provide the TKIP TX MIC key as it's not needed in client mode,
9 and thus the comparison will always return false.
10
11 For client mode, thus always zero out the TX MIC key part before
12 doing the comparison in order to avoid accepting the reinstall
13 of the key with identical encryption and RX MIC key, but not the
14 same TX MIC key (since the supplicant provides the real one.)
15
16 Fixes: fdf7cb4185b6 ("mac80211: accept key reinstall without changing anything")
17 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
18 ---
19 net/mac80211/key.c | 36 ++++++++++++++++++++++++++++++++++--
20 1 file changed, 34 insertions(+), 2 deletions(-)
21
22 --- a/net/mac80211/key.c
23 +++ b/net/mac80211/key.c
24 @@ -610,6 +610,39 @@ void ieee80211_key_free_unused(struct ie
25 ieee80211_key_free_common(key);
26 }
27
28 +static bool ieee80211_key_identical(struct ieee80211_sub_if_data *sdata,
29 + struct ieee80211_key *old,
30 + struct ieee80211_key *new)
31 +{
32 + u8 tkip_old[WLAN_KEY_LEN_TKIP], tkip_new[WLAN_KEY_LEN_TKIP];
33 + u8 *tk_old, *tk_new;
34 +
35 + if (!old || new->conf.keylen != old->conf.keylen)
36 + return false;
37 +
38 + tk_old = old->conf.key;
39 + tk_new = new->conf.key;
40 +
41 + /*
42 + * In station mode, don't compare the TX MIC key, as it's never used
43 + * and offloaded rekeying may not care to send it to the host. This
44 + * is the case in iwlwifi, for example.
45 + */
46 + if (sdata->vif.type == NL80211_IFTYPE_STATION &&
47 + new->conf.cipher == WLAN_CIPHER_SUITE_TKIP &&
48 + new->conf.keylen == WLAN_KEY_LEN_TKIP &&
49 + !(new->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
50 + memcpy(tkip_old, tk_old, WLAN_KEY_LEN_TKIP);
51 + memcpy(tkip_new, tk_new, WLAN_KEY_LEN_TKIP);
52 + memset(tkip_old + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 0, 8);
53 + memset(tkip_new + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 0, 8);
54 + tk_old = tkip_old;
55 + tk_new = tkip_new;
56 + }
57 +
58 + return !crypto_memneq(tk_old, tk_new, new->conf.keylen);
59 +}
60 +
61 int ieee80211_key_link(struct ieee80211_key *key,
62 struct ieee80211_sub_if_data *sdata,
63 struct sta_info *sta)
64 @@ -635,8 +668,7 @@ int ieee80211_key_link(struct ieee80211_
65 * Silently accept key re-installation without really installing the
66 * new version of the key to avoid nonce reuse or replay issues.
67 */
68 - if (old_key && key->conf.keylen == old_key->conf.keylen &&
69 - !crypto_memneq(key->conf.key, old_key->conf.key, key->conf.keylen)) {
70 + if (ieee80211_key_identical(sdata, old_key, key)) {
71 ieee80211_key_free_unused(key);
72 ret = 0;
73 goto out;