Mon, 24 Oct 2016 19:36:08 +0300 було написано Adrian Chadd <adr...@freebsd.org>:

Hi!

hiya,

So I have my ath10k driver port up and running in 11abg (not n/ac)
mode. The hardware is .. highly offload-y. There are three/four data
pipelines - "raw" mode, "native wifi" mode, "ethernet" mode, and
"management TX/RX" mode.

* "raw" mode is raw, untouched 802.11 frames. This is the most
flexible but it means we have to do software encryption and A-MSDU
encap/decap.
* "native wifi" mode is microsoft 802.11 framing. This is like 802.11,
but there's no QoS field. Yes, the QoS field is in the descriptor
field and the hardware will add/delete it for you.
* "ethernet" mode is 802.3 encap/decap ethernet.
* "management" mode is a separate TX/RX pipeline for management frames
(eg beacons, probe requests, etc.) The firmware is the normal target
for management frames and it takes care of sending up frames that the
stack needs to see.

Now, this makes crypto a bit of a pain to implement. Notably:

* There's no hardware key index that we see. It's all done per-peer.
So, each peer has the 0..4 wep key slot, then I think 0..4 for
pairwise keys (even though we only support keyidx 0 for now) with
flags to say "current TX key (for WEP), "pairwise", "group" keys.
* The group key is per-peer - so no, you don't program it in with an
address of ff:ff:ff:ff:ff:ff. It needs to be the BSS MAC.


That's similar to wpi(4) / iwn(4) crypto:
- they has some special 'set global WEP keys 0..3' firmware command;
- every node (24 for wpi(4), 16 (?) for iwn(4) has its own Rx key table
(8 pairwise + 8 group).
- encryption key is set in Tx descriptor.
(BTW, that's already implemented in wpi(4) (AES-CCM only))


* For raw mode, you don't need any keys, just send frames.
* For native wifi (and I'm guessing ethernet) you have to add a CLEAR
GTK/PMK key to a peer before it'll start transmitting traffic to said
peer - the firmware buffers frames until the four-way handshake is
done.
* For QoS traffic the hardware/firmware seems to corrupt software
encryption. Which, if you think about it, makes sense - the hardware
has to insert the QoS header into the frame and then transmit it,
which means if it makes /any/ change to make the packet contents not
line up, it won't decrypt right.

The mac80211/ath10k paths do software encryption/decryption for GCMP,
which we currently don't support. So there /is/ some way to do
completely software encryption/decryption, as long as it's non-QoS
management frame style traffic.

So those are the annoying bits. The net80211 bits that need to change are:

* The encryption hardware doesn't want an IV, FCS or MIC - it instead
will add the IV, MIC and WEP FCS itself. So during encap we shouldn't
provide it.
* .. and for management traffic, it depends. Sometimes it does,
sometimes it doesn't.
* For decryption, the hardware will fully decrypt the frame, including
stripping IV/MIC/WEPFCS. It instead passes up flags in the descriptor
to say "decrypted ok", "MIC failed", "CRC/FCS failed", etc. So a lot
of the decap path can't run - there's no IV to get a keyindex from,
and there's no MIC to check against / strip.


run(4) does something similar - it does not call ieee80211_crypto_encap()
for Tx and checks Rx descriptor flags before passing the frame to net80211


* There's no hardware keyindex - right now we have some kooky pointer
magic to check if a given key is a global key (0..3) or not, rather
than having a separate keyidx to hw_keyidx / hw_keyidx_rx. I think we
should fix that up.

And like other parts, key programming requires sleeping, which our
current net80211 key management code doesn't let us do. So I'll have
to teach the driver about a key update taskqueue + queue like urtwn,
etc has - but ideally net80211 would do this for us.

So, I do have it up and running with net80211 hacks to do the above.
It's not very pretty, but it does work. But I'd like to start thinking
about how to support these crypto offload modes in a more useful
fashion. Notably:

* per-key flags to say "don't add IV for non-mgmt", "don't add IV for
mgmt" - which is backwards compatible with what we currently do, but
is the exact opposite of what linux does. I'd kinda like to instead
add flags that say "add IV" and "add MIC" for "mgmt" or "non-mgmt",
and then teach the handful of drivers about it as appropriate.

* the input paths need to know about the encrypted offload flags.
There's no FC1_PROTECTED set for hardware-decrypted frames, they look
exactly like decrypted frames do normally.

* the input paths also need to know about stripped IV, MIC and FCSWEP.
Ie, none of the normal crypto_decap module paths can run as we can't
verify things - only that the frame was initially encrypted. So:

* ieee80211_crypto_decap() has to be able to say "this frame is fine,
but there's no key, so don't treat that as an error"; and
* ieee80211_crypto_demic() has to be able to take a NULL key, and run
the demic check against the RX flags - and if it fails, call the mic
failure notify path directly.

Yes, this also means there's no RSC/TSC PN tracking for CCMP/TKIP paths.

So with all of that - I'd appreciate some feedback/comments. I'm going
to start undoing my hacks and turning them into a set of cleanish
pieces, but the real "hm!" is what to do about default flag behaviour
for keys and whether to do what mac80211 does.

Thanks!


-adrian
_______________________________________________
freebsd-wireless@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"
_______________________________________________
freebsd-wireless@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"

Reply via email to