Date: Mon, 24 Oct 2016 21:55:08 +0300 From: "Andriy Voskoboinyk" <avos@freebsd.org> To: "Adrian Chadd" <adrian@freebsd.org> Cc: "freebsd-wireless@freebsd.org" <freebsd-wireless@freebsd.org> Subject: Re: net80211 offload, crypto offload pieces Message-ID: <op.ypuph6ly4dikkl@localhost> In-Reply-To: <CAJ-Vmo=EuDFnA8vkH7nt4ropyXSSgKJxr%2BV8Q7GvctpUq-Fz3g@mail.gmail.com> References: <CAJ-Vmo=EuDFnA8vkH7nt4ropyXSSgKJxr%2BV8Q7GvctpUq-Fz3g@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Mon, 24 Oct 2016 19:36:08 +0300 =D0=B1=D1=83=D0=BB=D0=BE =D0=BD=D0=B0=D0= =BF=D0=B8=D1=81=D0=B0=D0=BD=D0=BE Adrian Chadd = <adrian@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 net802= 11 > * 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 path= s. > > 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-unsubscribe@freebsd.org"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?op.ypuph6ly4dikkl>