Commit 5125e4a4 authored by Jason A. Donenfeld's avatar Jason A. Donenfeld Committed by Sasha Levin

mac80211/wpa: use constant time memory comparison for MACs

[ Upstream commit 98c67d18 ]

Otherwise, we enable all sorts of forgeries via timing attack.
Signed-off-by: default avatarJason 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: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarSasha Levin <alexander.levin@verizon.com>
parent 1a8dacfb
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <net/mac80211.h> #include <net/mac80211.h>
#include <crypto/aes.h> #include <crypto/aes.h>
#include <crypto/algapi.h>
#include "ieee80211_i.h" #include "ieee80211_i.h"
#include "michael.h" #include "michael.h"
...@@ -152,7 +153,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) ...@@ -152,7 +153,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
michael_mic(key, hdr, data, data_len, mic); michael_mic(key, hdr, data, data_len, mic);
if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) if (crypto_memneq(mic, data + data_len, MICHAEL_MIC_LEN))
goto mic_fail; goto mic_fail;
/* remove Michael MIC from payload */ /* remove Michael MIC from payload */
...@@ -1034,7 +1035,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) ...@@ -1034,7 +1035,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
bip_aad(skb, aad); bip_aad(skb, aad);
ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
skb->data + 24, skb->len - 24, mic); skb->data + 24, skb->len - 24, mic);
if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
key->u.aes_cmac.icverrors++; key->u.aes_cmac.icverrors++;
return RX_DROP_UNUSABLE; return RX_DROP_UNUSABLE;
} }
...@@ -1084,7 +1085,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) ...@@ -1084,7 +1085,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
bip_aad(skb, aad); bip_aad(skb, aad);
ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
skb->data + 24, skb->len - 24, mic); skb->data + 24, skb->len - 24, mic);
if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
key->u.aes_cmac.icverrors++; key->u.aes_cmac.icverrors++;
return RX_DROP_UNUSABLE; return RX_DROP_UNUSABLE;
} }
...@@ -1188,7 +1189,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx) ...@@ -1188,7 +1189,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
skb->data + 24, skb->len - 24, skb->data + 24, skb->len - 24,
mic) < 0 || mic) < 0 ||
memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
key->u.aes_gmac.icverrors++; key->u.aes_gmac.icverrors++;
return RX_DROP_UNUSABLE; return RX_DROP_UNUSABLE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment