d80211: fix WEP on big endian cpus
Subsystems (2)
PATCH 1/1 d80211: fix WEP on big endian cpus
The ICV is transmitted on the network as a 4 byte little endian quantity. WEP encryption needs to swap the bytes before transmission and decryption needs to swap bytes before ICV verification.
net/d80211/wep.c +4 -1
@@ -121,9 +121,11 @@ {struct scatterlist sg;u32 *icv; +u32 crc; icv = (u32 *)(data + data_len); - *icv = ~crc32_le (~0 , data, data_len); + crc = ~crc32_le (~0 , data, data_len); + *icv =cpu_to_le32 (crc);crypto_cipher_setkey (tfm, rc4key, klen); sg.page =virt_to_page (data);
@@ -196,6 +198,7 @@crypto_cipher_decrypt (tfm, &sg, &sg, sg.length); crc = ~crc32_le (~0 , data, data_len); + crc =cpu_to_le32 (crc);if (memcmp (&crc, data + data_len,WEP_ICV_LEN ) !=0 )/* ICV mismatch */ return -1 ;
--
Quoted 3 lines · David Kimdon
The ICV is transmitted on the network as a 4 byte little endian quantity. WEP encryption needs to swap the bytes before transmission and decryption needs to swap bytes before ICV verification.
Holy shit, this fixes the bug I am hunting for hours at the moment! I tested this patch and it works. Thanks very much, you saved me hours. ;)
John (Jiri), please apply this one.
Quoted 32 lines
Index:
wireless-dev/net/d80211/wep.c
===================================================================net/d80211/wep.c +4
-3@@ -121,9 +121,11 @@ {struct scatterlist sg;u32 *icv; +u32 crc; icv = (u32 *)(data + data_len); - *icv = ~crc32_le (~0 , data, data_len); + crc = ~crc32_le (~0 , data, data_len); + *icv =cpu_to_le32 (crc);crypto_cipher_setkey (tfm, rc4key, klen); sg.page =virt_to_page (data);@@ -196,6 +198,7 @@crypto_cipher_decrypt (tfm, &sg, &sg, sg.length); crc = ~crc32_le (~0 , data, data_len); + crc =cpu_to_le32 (crc);if (memcmp (&crc, data + data_len,WEP_ICV_LEN ) !=0 )/* ICV mismatch */ return -1 ; -- -To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Greetings Michael.
Huh. I assumed crc32_le gave us the result in little endian, but I guess that's wrong.
I've attached another patch which basically does the same thing but adds some sparse bitwise annotations to make things clear. Also, it has a signed-off-by line. :)
d80211: fix WEP on big endian cpus
This patch fixes the endian issues with the ICV in WEP, as pointed out by David Kimdon <[email protected]>, and uses __le32 where appropriate to make things clear.
---
net/d80211/wep.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
net/d80211/wep.c +5 -5
@@ -120,10 +120,10 @@ void ieee80211_wep_encrypt_data(struct c size_t klen, u8 *data, size_t data_len) { struct scatterlist sg; -u32 *icv; +__le32 *icv; - icv = (u32 *)(data + data_len); - *icv = ~crc32_le (~0 , data, data_len); + icv = (__le32 *)(data + data_len); + *icv =cpu_to_le32 (~crc32_le (~0 , data, data_len));crypto_cipher_setkey (tfm, rc4key, klen); sg.page =virt_to_page (data);
@@ -187,7 +187,7 @@ int ieee80211_wep_decrypt_data(struct cr size_t klen, u8 *data, size_t data_len) { struct scatterlist sg; -u32 crc; +__le32 crc;crypto_cipher_setkey (tfm, rc4key, klen); sg.page =virt_to_page (data);
@@ -195,7 +195,7 @@ int ieee80211_wep_decrypt_data(struct cr sg.length = data_len +WEP_ICV_LEN ;crypto_cipher_decrypt (tfm, &sg, &sg, sg.length); - crc = ~crc32_le (~0 , data, data_len); + crc =cpu_to_le32 (~crc32_le (~0 , data, data_len));if (memcmp (&crc, data + data_len,WEP_ICV_LEN ) !=0 )/* ICV mismatch */ return -1 ;
Jiri Benc
AppliedSun, 10 Sep 2006 17:47:16 -0400, Michael Wu pise:
Quoted 3 lines
This patch fixes the endian issues with the ICV in WEP, as pointed out by David Kimdon <[email protected]>, and uses
__le32where appropriate to make things clear.
Applied to my tree. Thanks for the patch!
Jiri
Signature · 2 lines
Jiri Benc SUSE Labs