The 802.11 specification specifically calls out that the GCMP AES uses the CCMP AES specification, so we can re-use this here. Changes during refactoring: * the first block (b0) needs the priority field populated, which was being done inline with the CCMP AAD assembly. So write a new function that implements just that. * Use IEEE80211_IS_QOS_ANY() in the AAD assembly; 802.11-2020 12.5.3.3.3 (Construct AAD) talks about frames with QoS control field, not specifically QoS data frames (ie, not avoiding PS-POLL.) * mask the HTC/ORDER bit in the FC if the data frame contains a QoS control field. Again, see 802.11-2020 12.5.3.3.3. * Add extra comments about missing items and functionality for later implementation.
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Skipped - Unit
Tests Skipped - Build Status
Buildable 62966 Build 59850: arc lint + arc unit
Event Timeline
ok, now I've tested with:
- rtwn, HW encryption, CCMP-128
- run, HW encryption, CCMP-128
- uath, SW encryption, CCMP-128 and GCMP-128
sys/net80211/ieee80211_crypto.c | ||
---|---|---|
955 | i /really/ want to verify what the right QoS check is here. in 802.11-2020 12.5.3.3.3 (Construct AAD) it only talks about the presence or not of the QoS field, NOT that it needs to have an 802.11 sequence number (ie a data subtype.) Let's go nail this down before i land this! |
sys/net80211/ieee80211_crypto.c | ||
---|---|---|
955 | 9.2.4.1.3 In Data frames, the most significant bit (MSB) of the Subtype subfield, B 7, is defined as the QoS subfield -> IEEE80211_IS_QOS_ANY I would say but in practice they both (IEEE80211_IS_QOS_ANY and IEEE80211_QOS_HAS_SEQ) check for the same thing (0x80 is 0x80 is MSB set). |
sys/net80211/ieee80211_crypto.c | ||
---|---|---|
955 |
Yeah that's why it looked slightly wrong to me. I think it should be IEEE80211_IS_QOS_ANY() because technically speaking, it READS like QOS NULL-DATA frames should still be encrypted. IEEE80211_QOS_HAS_SEQ() is more designed for sequence number assignment / checking, esp when forming A-MPDUs. So, I think I'll convert this code to IEEE80211_IS_QOS_ANY(). Is that OK with you? |
sys/net80211/ieee80211_crypto.c | ||
---|---|---|
921 | uint8_t ? well technically uint16_t but ... | |
952 | My suggestion given it's so nice that the optional bits are at the end is to use variables and acquire the values upfront:
Should make the code simpler and more readable, reduce duplication, and follow the documented plot some better. | |
955 | I haven't checked if an older spec is more clear about the wording. | |
982 | Following-up on my above suggestion: | |
sys/net80211/ieee80211_crypto_ccmp.c | ||
445 | Sorry but too much code duplication ;-) You do realize that bth code paths here are the same? If my above suggestion works you can save it all ;-) | |
505 | b0[1] = ... if you implement my suggestion | |
sys/net80211/ieee80211_crypto_gcmp.c | ||
548 | this would be void and if I am not mistaken (and is the only thing I do not fully like but passing &aad_len iitlaized to GCM_AAD_LEN to ieee80211_crypto_init_aad() instead and returning it updated is also not much better. | |
567 | and aad_len here would be be16toh(*(const uint16_t *)aad) if I am not mistaken. |
Thinking about it, i'd rather do the big cleanup in a separate diff versus the refactoring diff I'm doing here.
I do agree with your suggestions in principle, I just think combining both a refactor / re-organise and the code clean-up work in one big hit would make it hard to debug if something subtle IS busted.
What do you think? i'm happy to do it once the rest of the stack lands.