mac80211: Fix FC masking in BIP AAD generation

The bits used in the mask were off-by-one and ended up masking PwrMgt,
MoreData, Protected fields instead of Retry, PwrMgt, MoreData. Fix this
and to mask the correct fields. While doing so, convert the code to mask
the full FC using IEEE80211_FCTL_* defines similarly to how CCMP AAD is
built.

Since BIP is used only with broadcast/multicast management frames, the
Retry field is always 0 in these frames. The Protected field is also
zero to maintain backwards compatibility. As such, the incorrect mask
here does not really cause any problems for valid frames. In theory, an
invalid BIP frame with Retry or Protected field set to 1 could be
rejected because of BIP validation. However, no such frame should show
up with standard compliant implementations, so this does not cause
problems in normal BIP use.

Signed-off-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Jouni Malinen 2012-09-30 19:47:40 +03:00 коммит произвёл Johannes Berg
Родитель 7ce8c7a343
Коммит 33766368f6
1 изменённых файлов: 8 добавлений и 3 удалений

Просмотреть файл

@ -545,14 +545,19 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
static void bip_aad(struct sk_buff *skb, u8 *aad)
{
__le16 mask_fc;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
/* BIP AAD: FC(masked) || A1 || A2 || A3 */
/* FC type/subtype */
aad[0] = skb->data[0];
/* Mask FC Retry, PwrMgt, MoreData flags to zero */
aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6));
mask_fc = hdr->frame_control;
mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM |
IEEE80211_FCTL_MOREDATA);
put_unaligned(mask_fc, (__le16 *) &aad[0]);
/* A1 || A2 || A3 */
memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN);
memcpy(aad + 2, &hdr->addr1, 3 * ETH_ALEN);
}