802.11 Decrypt: Fix AAD Calculation when HT-Control present in a QoS Data Frame

The current implementation misses an edge case, where bit 15 of the FC Field
must be zeroed in case a QoS Control field is present (IEEE 802.11 12.5.3.3.3),
which results in a wrong AAD and subsequently in the failure of the packet
decryption for QoS Data Frame carrying a HT Control Field (indicated by bit
15 set to 1).

In addition the field 14 must be 1, which is ensured explicitly (the author is
not sure if the code is reachable by frames which do not have bit 14 set to
one).
This commit is contained in:
Marius Preuten 2021-09-01 12:54:18 +02:00 committed by AndersBroman
parent cfc60b3f6e
commit e5e37add9a
1 changed files with 7 additions and 2 deletions

View File

@ -21,6 +21,7 @@
#define FC0_AAD_MASK 0x8f
#define FC1_AAD_MASK 0xc7
#define FC1_AAD_QOS_MASK 0x47
/****************************************************************************/
/* Internal macros */
@ -41,7 +42,7 @@ void dot11decrypt_construct_aad(
int alen = 22;
/* AAD:
* FC with bits 4..6 and 11..13 masked to zero; 14 is always one
* FC with bits 4..6 and 11..13 masked to zero; 14 is always one; 15 zero when QoS Control field present
* A1 | A2 | A3
* SC with bits 4..15 (seq#) masked to zero
* A4 (if present)
@ -54,7 +55,11 @@ void dot11decrypt_construct_aad(
} else {
aad[0] = wh->fc[0];
}
aad[1] = (UINT8)(wh->fc[1] & FC1_AAD_MASK);
if (DOT11DECRYPT_IS_QOS_DATA(wh)) {
aad[1] = (UINT8)((wh->fc[1] & FC1_AAD_QOS_MASK) | 0x40);
} else {
aad[1] = (UINT8)((wh->fc[1] & FC1_AAD_MASK) | 0x40);
}
memcpy(aad + 2, (guint8 *)wh->addr1, DOT11DECRYPT_MAC_LEN);
memcpy(aad + 8, (guint8 *)wh->addr2, DOT11DECRYPT_MAC_LEN);
memcpy(aad + 14, (guint8 *)wh->addr3, DOT11DECRYPT_MAC_LEN);