net80211 offload, crypto offload pieces

Andriy Voskoboinyk avos at freebsd.org
Mon Oct 24 19:02:10 UTC 2016


Mon, 24 Oct 2016 19:36:08 +0300 було написано Adrian Chadd  
<adrian at 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 at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
> To unsubscribe, send any mail to  
> "freebsd-wireless-unsubscribe at freebsd.org"


More information about the freebsd-wireless mailing list