Discussion:
wi(4) and WEP on NetBSD 4.0
(too old to reply)
Quentin Garnier
2007-11-26 11:02:13 UTC
Permalink
Hi,

I upgraded a machine from 2.0 to 4.0 this week-end. It serves among
other things as an access point for a home 11b network, using a wi(4)
card.

I was faced with two issues related to WEP, one in the RX path, the
other in the TX path.

The RX path one is easier: frames were dropped because of _F_DROPUNENC
which is set by default. The reason for that is the following block in
sys/dev/ic/wi.c, in wi_rx_intr():

if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
/*
* WEP is decrypted by hardware. Clear WEP bit
* header for ieee80211_input().
*/
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
}

Apparently, the net80211 subsystem has changed enough that this does the
wrong thing: as the bit is cleared, ieee80211_input() thinks it is an
unencrypted frame, so it drops it per _F_DROPUNENC. I believe that the
part that has changed in net80211 is that the codec for WEP is aware the
hardware is supposed to do the actual deciphering, hence it doesn't do
it.

The fix for that issue is to just comment the block shown above.

I'm told by someone that wi+WEP works for him in NetBSD 4.0. My reading
of the code doesn't show any place where the fact that I run it in
hostap mode changes anything, so I'm rather surprised.

The TX issue is different, and I think it means a few things have to
change in net80211 so it can be fixed properly. I don't know how the
current net80211 code in FreeBSD is different from what we have, but a
quick glance at it didn't let me see how they could have fixed it.

The bottom of the issue is that according to comments in the wi(4)
driver, the chip has a bug which means TX frames must be encoded by the
software. However, it will still happily do the decryption for RX
frames. The problem is that there is no way for the driver to tell the
net80211 layer to do encryption by software, but not do decryption.

My quick workaround (as in "this has to work _now_") was simply to
comment out the check for _KEY_SWCRYPT in _crypto_wep.c:wep_encap().

I started playing with the idea of adding flags or capabilities to
distinguish between encryption and decryption. I have code, but I
haven't tested it yet.

Another solution would be to change wi so that it doesn't do decryption
in hw when it is in hostap mode. But even in that case we have to make
sure the WEP keys structures are updated when transitioning from
infrastructure or adhoc mode to hostap, so in that regards both
solutions are rather equivalent.

Anything I would have missed on my way, before I go digging further?

Here's the mentioned untested code:

http://taryn.cubidou.net/~cube/netbsd/wi.diff
--
Quentin Garnier - ***@cubidou.net - ***@NetBSD.org
"See the look on my face from staying too long in one place
[...] every time the morning breaks I know I'm closer to falling"
KT Tunstall, Saving My Face, Drastic Fantastic, 2007.
David Young
2007-11-26 16:13:05 UTC
Permalink
Post by Quentin Garnier
Hi,
I upgraded a machine from 2.0 to 4.0 this week-end. It serves among
other things as an access point for a home 11b network, using a wi(4)
card.
I was faced with two issues related to WEP, one in the RX path, the
other in the TX path.
The RX path one is easier: frames were dropped because of _F_DROPUNENC
which is set by default. The reason for that is the following block in
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
/*
* WEP is decrypted by hardware. Clear WEP bit
* header for ieee80211_input().
*/
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
}
Apparently, the net80211 subsystem has changed enough that this does the
wrong thing: as the bit is cleared, ieee80211_input() thinks it is an
unencrypted frame, so it drops it per _F_DROPUNENC. I believe that the
part that has changed in net80211 is that the codec for WEP is aware the
hardware is supposed to do the actual deciphering, hence it doesn't do
it.
The fix for that issue is to just comment the block shown above.
I'm told by someone that wi+WEP works for him in NetBSD 4.0. My reading
of the code doesn't show any place where the fact that I run it in
hostap mode changes anything, so I'm rather surprised.
Crypto works differently on wi in hostap mode than otherwise: as you
mention below, Tx WEP is broken, Rx WEP works, and net80211 is not
especially accommodating of that asymmetry.
Post by Quentin Garnier
The TX issue is different, and I think it means a few things have to
change in net80211 so it can be fixed properly. I don't know how the
current net80211 code in FreeBSD is different from what we have, but a
quick glance at it didn't let me see how they could have fixed it.
The bottom of the issue is that according to comments in the wi(4)
driver, the chip has a bug which means TX frames must be encoded by the
software. However, it will still happily do the decryption for RX
frames. The problem is that there is no way for the driver to tell the
net80211 layer to do encryption by software, but not do decryption.
I ran into a similar problem in rtw, where some hardware revisions have
WEP Tx bugs but not WEP Rx bugs.
Post by Quentin Garnier
My quick workaround (as in "this has to work _now_") was simply to
comment out the check for _KEY_SWCRYPT in _crypto_wep.c:wep_encap().
In rtw, I clone ieee80211_cipher_wep and override the ic_decap() member
with rtw_wep_decap().
Post by Quentin Garnier
I started playing with the idea of adding flags or capabilities to
distinguish between encryption and decryption. I have code, but I
haven't tested it yet.
That might be best.

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933 ext 24

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Quentin Garnier
2007-11-26 16:16:57 UTC
Permalink
Post by David Young
Post by Quentin Garnier
Hi,
I upgraded a machine from 2.0 to 4.0 this week-end. It serves among
other things as an access point for a home 11b network, using a wi(4)
card.
I was faced with two issues related to WEP, one in the RX path, the
other in the TX path.
The RX path one is easier: frames were dropped because of _F_DROPUNENC
which is set by default. The reason for that is the following block in
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
/*
* WEP is decrypted by hardware. Clear WEP bit
* header for ieee80211_input().
*/
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
}
Apparently, the net80211 subsystem has changed enough that this does the
wrong thing: as the bit is cleared, ieee80211_input() thinks it is an
unencrypted frame, so it drops it per _F_DROPUNENC. I believe that the
part that has changed in net80211 is that the codec for WEP is aware the
hardware is supposed to do the actual deciphering, hence it doesn't do
it.
The fix for that issue is to just comment the block shown above.
I'm told by someone that wi+WEP works for him in NetBSD 4.0. My reading
of the code doesn't show any place where the fact that I run it in
hostap mode changes anything, so I'm rather surprised.
Crypto works differently on wi in hostap mode than otherwise: as you
mention below, Tx WEP is broken, Rx WEP works, and net80211 is not
especially accommodating of that asymmetry.
Yes but my point here is that it seems to me that the RX bug should
happen in modes other than hostap. I don't see anything specific to
hostap in that code path.
--
Quentin Garnier - ***@cubidou.net - ***@NetBSD.org
"See the look on my face from staying too long in one place
[...] every time the morning breaks I know I'm closer to falling"
KT Tunstall, Saving My Face, Drastic Fantastic, 2007.
David Young
2007-11-26 16:24:27 UTC
Permalink
Post by Quentin Garnier
Post by David Young
Crypto works differently on wi in hostap mode than otherwise: as you
mention below, Tx WEP is broken, Rx WEP works, and net80211 is not
especially accommodating of that asymmetry.
Yes but my point here is that it seems to me that the RX bug should
happen in modes other than hostap. I don't see anything specific to
hostap in that code path.
I am guessing that in other modes, the NIC decapsulates WEP frames after
decrypting, and it also strips the WEP flag.

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933 ext 24

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Quentin Garnier
2007-11-26 16:44:31 UTC
Permalink
Post by David Young
Post by Quentin Garnier
Post by David Young
Crypto works differently on wi in hostap mode than otherwise: as you
mention below, Tx WEP is broken, Rx WEP works, and net80211 is not
especially accommodating of that asymmetry.
Yes but my point here is that it seems to me that the RX bug should
happen in modes other than hostap. I don't see anything specific to
hostap in that code path.
I am guessing that in other modes, the NIC decapsulates WEP frames after
decrypting, and it also strips the WEP flag.
But then _F_DROPUNENC would fire just the same way, wouldn't it?
--
Quentin Garnier - ***@cubidou.net - ***@NetBSD.org
"See the look on my face from staying too long in one place
[...] every time the morning breaks I know I'm closer to falling"
KT Tunstall, Saving My Face, Drastic Fantastic, 2007.
David Young
2007-11-26 23:07:47 UTC
Permalink
Post by Quentin Garnier
Post by David Young
Post by Quentin Garnier
Post by David Young
Crypto works differently on wi in hostap mode than otherwise: as you
mention below, Tx WEP is broken, Rx WEP works, and net80211 is not
especially accommodating of that asymmetry.
Yes but my point here is that it seems to me that the RX bug should
happen in modes other than hostap. I don't see anything specific to
hostap in that code path.
I am guessing that in other modes, the NIC decapsulates WEP frames after
decrypting, and it also strips the WEP flag.
But then _F_DROPUNENC would fire just the same way, wouldn't it?
You're right. However, wi contains a grotty workaround.
See wi_mend_flags().

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933 ext 24

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...