Skip to contentSkip to conversation

d80211: fix WEP on big endian cpus

PATCH Applied David Kimdon 4 participants 4 messages Sep 10, 2006 – Sep 21, 2006

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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
Index: wireless-dev/net/d80211/wep.c
===================================================================
@@ -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;

--

Acked-by on v1 1/1
#1 lore raw
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.
#2 lore raw
In reply to David Kimdon

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
index c3e4728..22c2e53 100644
@@ -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;
Applied
#3 lore raw

Sun, 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 __le32 where appropriate to make things clear.

Applied to my tree. Thanks for the patch!

Jiri

Signature · 2 lines
Jiri Benc
SUSE Labs