diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-06-09 22:59:12 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2017-06-13 04:24:34 -0400 |
commit | 98c67d187db7808b1f3c95f2110dd4392d034182 (patch) | |
tree | eafa0fac1f1551cac32b8326e955cb20b516e6f9 | |
parent | c87905bec5dad66aa6bb43d11502cafdb33e07db (diff) |
mac80211/wpa: use constant time memory comparison for MACs
Otherwise, we enable all sorts of forgeries via timing attack.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-wireless@vger.kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/mac80211/wpa.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index c1ef22df865f..cc19614ff4e6 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm/unaligned.h> | 17 | #include <asm/unaligned.h> |
18 | #include <net/mac80211.h> | 18 | #include <net/mac80211.h> |
19 | #include <crypto/aes.h> | 19 | #include <crypto/aes.h> |
20 | #include <crypto/algapi.h> | ||
20 | 21 | ||
21 | #include "ieee80211_i.h" | 22 | #include "ieee80211_i.h" |
22 | #include "michael.h" | 23 | #include "michael.h" |
@@ -153,7 +154,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
153 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; | 154 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; |
154 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; | 155 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; |
155 | michael_mic(key, hdr, data, data_len, mic); | 156 | michael_mic(key, hdr, data, data_len, mic); |
156 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) | 157 | if (crypto_memneq(mic, data + data_len, MICHAEL_MIC_LEN)) |
157 | goto mic_fail; | 158 | goto mic_fail; |
158 | 159 | ||
159 | /* remove Michael MIC from payload */ | 160 | /* remove Michael MIC from payload */ |
@@ -1048,7 +1049,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
1048 | bip_aad(skb, aad); | 1049 | bip_aad(skb, aad); |
1049 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, | 1050 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, |
1050 | skb->data + 24, skb->len - 24, mic); | 1051 | skb->data + 24, skb->len - 24, mic); |
1051 | if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { | 1052 | if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { |
1052 | key->u.aes_cmac.icverrors++; | 1053 | key->u.aes_cmac.icverrors++; |
1053 | return RX_DROP_UNUSABLE; | 1054 | return RX_DROP_UNUSABLE; |
1054 | } | 1055 | } |
@@ -1098,7 +1099,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) | |||
1098 | bip_aad(skb, aad); | 1099 | bip_aad(skb, aad); |
1099 | ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, | 1100 | ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, |
1100 | skb->data + 24, skb->len - 24, mic); | 1101 | skb->data + 24, skb->len - 24, mic); |
1101 | if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { | 1102 | if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { |
1102 | key->u.aes_cmac.icverrors++; | 1103 | key->u.aes_cmac.icverrors++; |
1103 | return RX_DROP_UNUSABLE; | 1104 | return RX_DROP_UNUSABLE; |
1104 | } | 1105 | } |
@@ -1202,7 +1203,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx) | |||
1202 | if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, | 1203 | if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, |
1203 | skb->data + 24, skb->len - 24, | 1204 | skb->data + 24, skb->len - 24, |
1204 | mic) < 0 || | 1205 | mic) < 0 || |
1205 | memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { | 1206 | crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { |
1206 | key->u.aes_gmac.icverrors++; | 1207 | key->u.aes_gmac.icverrors++; |
1207 | return RX_DROP_UNUSABLE; | 1208 | return RX_DROP_UNUSABLE; |
1208 | } | 1209 | } |