^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2002-2004, Instant802 Networks, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2008, Jouni Malinen <j@w1.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2016-2017 Intel Deutschland GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2020-2021 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/ieee80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/mac80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <crypto/aes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <crypto/algapi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "ieee80211_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "michael.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "tkip.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "aes_ccm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "aes_cmac.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "aes_gmac.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "aes_gcm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "wpa.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) u8 *data, *key, *mic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) size_t data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct ieee80211_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct sk_buff *skb = tx->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (!tx->key || tx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (skb->len < hdrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) data = skb->data + hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) data_len = skb->len - hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Need to use software crypto for the test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) info->control.hw_key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) (info->flags & IEEE80211_TX_CTL_DONTFRAG ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ieee80211_hw_check(&tx->local->hw, SUPPORTS_TX_FRAG)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) !(tx->key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) IEEE80211_KEY_FLAG_PUT_MIC_SPACE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* hwaccel - with no need for SW-generated MMIC or MIC space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) tail = MICHAEL_MIC_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (!info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) tail += IEEE80211_TKIP_ICV_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (WARN(skb_tailroom(skb) < tail ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) skb_headroom(skb) < IEEE80211_TKIP_IV_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) "mmic: not enough head/tail (%d/%d,%d/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) skb_headroom(skb), IEEE80211_TKIP_IV_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) skb_tailroom(skb), tail))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) mic = skb_put(skb, MICHAEL_MIC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (tx->key->conf.flags & IEEE80211_KEY_FLAG_PUT_MIC_SPACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* Zeroed MIC can help with debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) memset(mic, 0, MICHAEL_MIC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) michael_mic(key, hdr, data, data_len, mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mic[0]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u8 *data, *key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) size_t data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u8 mic[MICHAEL_MIC_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct sk_buff *skb = rx->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * it makes no sense to check for MIC errors on anything other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * than data frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!ieee80211_is_data_present(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * No way to verify the MIC if the hardware stripped it or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * the IV with the key index. In this case we have solely rely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * on the driver to set RX_FLAG_MMIC_ERROR in the event of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * MIC failure report.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (status->flag & (RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (status->flag & RX_FLAG_MMIC_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) goto mic_fail_no_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) goto update_iv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Some hardware seems to generate Michael MIC failure reports; even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * though, the frame was not encrypted with TKIP and therefore has no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * MIC. Ignore the flag them to avoid triggering countermeasures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) !(status->flag & RX_FLAG_DECRYPTED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (rx->sdata->vif.type == NL80211_IFTYPE_AP && rx->key->conf.keyidx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * APs with pairwise keys should never receive Michael MIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * errors for non-zero keyidx because these are reserved for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * group keys and only the AP is sending real multicast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * frames in the BSS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (status->flag & RX_FLAG_MMIC_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) goto mic_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (skb->len < hdrlen + MICHAEL_MIC_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (skb_linearize(rx->skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) hdr = (void *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) data = skb->data + hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) michael_mic(key, hdr, data, data_len, mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (crypto_memneq(mic, data + data_len, MICHAEL_MIC_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) goto mic_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* remove Michael MIC from payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) update_iv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* update IV in key information to be able to detect replays */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip.iv32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip.iv16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mic_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rx->key->u.tkip.mic_failures++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) mic_fail_no_key:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * In some cases the key can be unset - e.g. a multicast packet, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * a driver that supports HW encryption. Send up the key idx only if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * the key is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) cfg80211_michael_mic_failure(rx->sdata->dev, hdr->addr2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) is_multicast_ether_addr(hdr->addr1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) NL80211_KEYTYPE_GROUP :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) NL80211_KEYTYPE_PAIRWISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) rx->key ? rx->key->conf.keyidx : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct ieee80211_key *key = tx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int len, tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u64 pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u8 *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* hwaccel - with no need for software-generated IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) len = skb->len - hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) tail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) tail = IEEE80211_TKIP_ICV_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (WARN_ON(skb_tailroom(skb) < tail ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) skb_headroom(skb) < IEEE80211_TKIP_IV_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) pos = skb_push(skb, IEEE80211_TKIP_IV_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) pos += hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* the HW only needs room for the IV, but not the actual IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* Increase IV for the frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) pn = atomic64_inc_return(&key->conf.tx_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) pos = ieee80211_tkip_add_iv(pos, &key->conf, pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* hwaccel - with software IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* Add room for ICV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) skb_put(skb, IEEE80211_TKIP_ICV_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return ieee80211_tkip_encrypt_data(&tx->local->wep_tx_ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) key, skb, pos, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ieee80211_tx_set_protected(tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) skb_queue_walk(&tx->skbs, skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (tkip_encrypt_skb(tx, skb) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int hdrlen, res, hwaccel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct ieee80211_key *key = rx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct sk_buff *skb = rx->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (!ieee80211_is_data(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (!rx->sta || skb->len - hdrlen < 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* it may be possible to optimize this a bit more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (skb_linearize(rx->skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) hdr = (void *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Let TKIP code verify IV, but skip decryption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * In the case where hardware checks the IV as well,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * we don't even get here, see ieee80211_rx_h_decrypt()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (status->flag & RX_FLAG_DECRYPTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) hwaccel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) res = ieee80211_tkip_decrypt_data(&rx->local->wep_rx_ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) key, skb->data + hdrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) skb->len - hdrlen, rx->sta->sta.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) hdr->addr1, hwaccel, rx->security_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) &rx->tkip.iv32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) &rx->tkip.iv16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (res != TKIP_DECRYPT_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* Trim ICV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!(status->flag & RX_FLAG_ICV_STRIPPED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Remove IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) skb_pull(skb, IEEE80211_TKIP_IV_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) __le16 mask_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int a4_included, mgmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u8 qos_tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u16 len_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * Retry, PwrMgt, MoreData; set Protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) mgmt = ieee80211_is_mgmt(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mask_fc = hdr->frame_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (!mgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) mask_fc &= ~cpu_to_le16(0x0070);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) len_a = hdrlen - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) a4_included = ieee80211_has_a4(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (ieee80211_is_data_qos(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) qos_tid = ieee80211_get_tid(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) qos_tid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * mode authentication are not allowed to collide, yet both are derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * from this vector b_0. We only set L := 1 here to indicate that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * data size can be represented in (L+1) bytes. The CCM layer will take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * care of storing the data length in the top (L+1) bytes and setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * and clearing the other bits as is required to derive the two IVs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) b_0[0] = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Nonce: Nonce Flags | A2 | PN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) b_0[1] = qos_tid | (mgmt << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* AAD (extra authenticate-only data) / masked 802.11 header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) put_unaligned_be16(len_a, &aad[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) put_unaligned(mask_fc, (__le16 *)&aad[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Mask Seq#, leave Frag# */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) aad[23] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (a4_included) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) memcpy(&aad[24], hdr->addr4, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) aad[30] = qos_tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) aad[31] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) aad[24] = qos_tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static inline void ccmp_pn2hdr(u8 *hdr, u8 *pn, int key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) hdr[0] = pn[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) hdr[1] = pn[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) hdr[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) hdr[3] = 0x20 | (key_id << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) hdr[4] = pn[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) hdr[5] = pn[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) hdr[6] = pn[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) hdr[7] = pn[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) pn[0] = hdr[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) pn[1] = hdr[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) pn[2] = hdr[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) pn[3] = hdr[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) pn[4] = hdr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) pn[5] = hdr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) unsigned int mic_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct ieee80211_key *key = tx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int hdrlen, len, tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) u8 *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) u8 pn[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) u64 pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) u8 aad[CCM_AAD_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) u8 b_0[AES_BLOCK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) !((info->control.hw_key->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ieee80211_is_mgmt(hdr->frame_control))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * hwaccel has no need for preallocated room for CCMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * header or MIC fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) len = skb->len - hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) tail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) tail = mic_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (WARN_ON(skb_tailroom(skb) < tail ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* the HW only needs room for the IV, but not the actual IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) hdr = (struct ieee80211_hdr *) pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) pos += hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) pn64 = atomic64_inc_return(&key->conf.tx_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) pn[5] = pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) pn[4] = pn64 >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) pn[3] = pn64 >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) pn[2] = pn64 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) pn[1] = pn64 >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pn[0] = pn64 >> 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ccmp_pn2hdr(pos, pn, key->conf.keyidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* hwaccel - with software CCMP header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) pos += IEEE80211_CCMP_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ccmp_special_blocks(skb, pn, b_0, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) skb_put(skb, mic_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) unsigned int mic_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ieee80211_tx_set_protected(tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) skb_queue_walk(&tx->skbs, skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (ccmp_encrypt_skb(tx, skb, mic_len) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) unsigned int mic_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct ieee80211_key *key = rx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct sk_buff *skb = rx->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) u8 pn[IEEE80211_CCMP_PN_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) int queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!ieee80211_is_data(hdr->frame_control) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) !ieee80211_is_robust_mgmt_frame(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (status->flag & RX_FLAG_DECRYPTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (status->flag & RX_FLAG_MIC_STRIPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) mic_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (skb_linearize(rx->skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* reload hdr - skb might have been reallocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) hdr = (void *)rx->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (!rx->sta || data_len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ccmp_hdr2pn(pn, skb->data + hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) queue = rx->security_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) res = memcmp(pn, key->u.ccmp.rx_pn[queue],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) IEEE80211_CCMP_PN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (res < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) key->u.ccmp.replays++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (!(status->flag & RX_FLAG_DECRYPTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) u8 aad[2 * AES_BLOCK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) u8 b_0[AES_BLOCK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* hardware didn't decrypt/verify MIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ccmp_special_blocks(skb, pn, b_0, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (ieee80211_aes_ccm_decrypt(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) key->u.ccmp.tfm, b_0, aad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) skb->data + skb->len - mic_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (unlikely(ieee80211_is_frag(hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* Remove CCMP header and MIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (pskb_trim(skb, skb->len - mic_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) skb_pull(skb, IEEE80211_CCMP_HDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) __le16 mask_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u8 qos_tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) memcpy(j_0, hdr->addr2, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) memcpy(&j_0[ETH_ALEN], pn, IEEE80211_GCMP_PN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) j_0[13] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) j_0[14] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) j_0[AES_BLOCK_SIZE - 1] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* AAD (extra authenticate-only data) / masked 802.11 header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * FC | A1 | A2 | A3 | SC | [A4] | [QC]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) put_unaligned_be16(ieee80211_hdrlen(hdr->frame_control) - 2, &aad[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /* Mask FC: zero subtype b4 b5 b6 (if not mgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * Retry, PwrMgt, MoreData; set Protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) mask_fc = hdr->frame_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (!ieee80211_is_mgmt(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) mask_fc &= ~cpu_to_le16(0x0070);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) put_unaligned(mask_fc, (__le16 *)&aad[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* Mask Seq#, leave Frag# */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) aad[22] = *((u8 *)&hdr->seq_ctrl) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) aad[23] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (ieee80211_is_data_qos(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) qos_tid = ieee80211_get_tid(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) qos_tid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (ieee80211_has_a4(hdr->frame_control)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) memcpy(&aad[24], hdr->addr4, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) aad[30] = qos_tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) aad[31] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) aad[24] = qos_tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static inline void gcmp_pn2hdr(u8 *hdr, const u8 *pn, int key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) hdr[0] = pn[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) hdr[1] = pn[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) hdr[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) hdr[3] = 0x20 | (key_id << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) hdr[4] = pn[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) hdr[5] = pn[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) hdr[6] = pn[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) hdr[7] = pn[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static inline void gcmp_hdr2pn(u8 *pn, const u8 *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) pn[0] = hdr[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) pn[1] = hdr[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) pn[2] = hdr[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) pn[3] = hdr[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) pn[4] = hdr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) pn[5] = hdr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static int gcmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct ieee80211_key *key = tx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) int hdrlen, len, tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) u8 *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) u8 pn[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) u64 pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) u8 aad[GCM_AAD_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) u8 j_0[AES_BLOCK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) !((info->control.hw_key->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ieee80211_is_mgmt(hdr->frame_control))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* hwaccel has no need for preallocated room for GCMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * header or MIC fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) len = skb->len - hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) tail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) tail = IEEE80211_GCMP_MIC_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (WARN_ON(skb_tailroom(skb) < tail ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) skb_headroom(skb) < IEEE80211_GCMP_HDR_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) pos = skb_push(skb, IEEE80211_GCMP_HDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) memmove(pos, pos + IEEE80211_GCMP_HDR_LEN, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) skb_set_network_header(skb, skb_network_offset(skb) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) IEEE80211_GCMP_HDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* the HW only needs room for the IV, but not the actual IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) hdr = (struct ieee80211_hdr *)pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) pos += hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) pn64 = atomic64_inc_return(&key->conf.tx_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) pn[5] = pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) pn[4] = pn64 >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) pn[3] = pn64 >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) pn[2] = pn64 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) pn[1] = pn64 >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) pn[0] = pn64 >> 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) gcmp_pn2hdr(pos, pn, key->conf.keyidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* hwaccel - with software GCMP header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) pos += IEEE80211_GCMP_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) gcmp_special_blocks(skb, pn, j_0, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) skb_put(skb, IEEE80211_GCMP_MIC_LEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) ieee80211_crypto_gcmp_encrypt(struct ieee80211_tx_data *tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ieee80211_tx_set_protected(tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) skb_queue_walk(&tx->skbs, skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (gcmp_encrypt_skb(tx, skb) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct ieee80211_key *key = rx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct sk_buff *skb = rx->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) u8 pn[IEEE80211_GCMP_PN_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) int data_len, queue, mic_len = IEEE80211_GCMP_MIC_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!ieee80211_is_data(hdr->frame_control) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) !ieee80211_is_robust_mgmt_frame(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (status->flag & RX_FLAG_DECRYPTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (status->flag & RX_FLAG_MIC_STRIPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) mic_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (skb_linearize(rx->skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* reload hdr - skb might have been reallocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) hdr = (void *)rx->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (!rx->sta || data_len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) gcmp_hdr2pn(pn, skb->data + hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) queue = rx->security_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) res = memcmp(pn, key->u.gcmp.rx_pn[queue],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) IEEE80211_GCMP_PN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (res < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) key->u.gcmp.replays++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (!(status->flag & RX_FLAG_DECRYPTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) u8 aad[2 * AES_BLOCK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) u8 j_0[AES_BLOCK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* hardware didn't decrypt/verify MIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) gcmp_special_blocks(skb, pn, j_0, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (ieee80211_aes_gcm_decrypt(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) key->u.gcmp.tfm, j_0, aad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) skb->data + hdrlen + IEEE80211_GCMP_HDR_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) skb->data + skb->len -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) IEEE80211_GCMP_MIC_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (unlikely(ieee80211_is_frag(hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /* Remove GCMP header and MIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (pskb_trim(skb, skb->len - mic_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) skb_pull(skb, IEEE80211_GCMP_HDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct ieee80211_key *key = tx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) u8 *pos, iv_len = key->conf.iv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /* hwaccel has no need for preallocated head room */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (unlikely(skb_headroom(skb) < iv_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) pos = skb_push(skb, iv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) memmove(pos, pos + iv_len, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static inline int ieee80211_crypto_cs_pn_compare(u8 *pn1, u8 *pn2, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /* pn is little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) for (i = len - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (pn1[i] < pn2[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) else if (pn1[i] > pn2[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct ieee80211_key *key = rx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) const struct ieee80211_cipher_scheme *cs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) u8 *rx_pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) u8 *skb_pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) u8 qos_tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (!rx->sta || !rx->sta->cipher_scheme ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) !(status->flag & RX_FLAG_DECRYPTED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!ieee80211_is_data(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) cs = rx->sta->cipher_scheme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) data_len = rx->skb->len - hdrlen - cs->hdr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (data_len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (ieee80211_is_data_qos(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) qos_tid = ieee80211_get_tid(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) qos_tid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (skb_linearize(rx->skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) hdr = (struct ieee80211_hdr *)rx->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) rx_pn = key->u.gen.rx_pn[qos_tid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) skb_pn = rx->skb->data + hdrlen + cs->pn_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (ieee80211_crypto_cs_pn_compare(skb_pn, rx_pn, cs->pn_len) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) memcpy(rx_pn, skb_pn, cs->pn_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /* remove security header and MIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (pskb_trim(rx->skb, rx->skb->len - cs->mic_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) memmove(rx->skb->data + cs->hdr_len, rx->skb->data, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) skb_pull(rx->skb, cs->hdr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static void bip_aad(struct sk_buff *skb, u8 *aad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) __le16 mask_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* BIP AAD: FC(masked) || A1 || A2 || A3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* FC type/subtype */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* Mask FC Retry, PwrMgt, MoreData flags to zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) mask_fc = hdr->frame_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) IEEE80211_FCTL_MOREDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) put_unaligned(mask_fc, (__le16 *) &aad[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /* A1 || A2 || A3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) memcpy(aad + 2, &hdr->addr1, 3 * ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static inline void bip_ipn_set64(u8 *d, u64 pn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) *d++ = pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) *d++ = pn >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) *d++ = pn >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) *d++ = pn >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) *d++ = pn >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) *d = pn >> 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) static inline void bip_ipn_swap(u8 *d, const u8 *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) *d++ = s[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) *d++ = s[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) *d++ = s[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) *d++ = s[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) *d++ = s[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) *d = s[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct ieee80211_tx_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct ieee80211_key *key = tx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct ieee80211_mmie *mmie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) u8 aad[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) u64 pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) skb = skb_peek(&tx->skbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (info->control.hw_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) mmie = skb_put(skb, sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) mmie->element_id = WLAN_EID_MMIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) mmie->length = sizeof(*mmie) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) mmie->key_id = cpu_to_le16(key->conf.keyidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* PN = PN + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) pn64 = atomic64_inc_return(&key->conf.tx_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) bip_ipn_set64(mmie->sequence_number, pn64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) bip_aad(skb, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) skb->data + 24, skb->len - 24, mmie->mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct ieee80211_tx_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct ieee80211_key *key = tx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct ieee80211_mmie_16 *mmie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) u8 aad[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) u64 pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) skb = skb_peek(&tx->skbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) mmie = skb_put(skb, sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) mmie->element_id = WLAN_EID_MMIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) mmie->length = sizeof(*mmie) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) mmie->key_id = cpu_to_le16(key->conf.keyidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* PN = PN + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) pn64 = atomic64_inc_return(&key->conf.tx_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) bip_ipn_set64(mmie->sequence_number, pn64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) bip_aad(skb, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) skb->data + 24, skb->len - 24, mmie->mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct sk_buff *skb = rx->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct ieee80211_key *key = rx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct ieee80211_mmie *mmie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) u8 aad[20], mic[8], ipn[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (!ieee80211_is_mgmt(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* management frames are already linear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (skb->len < 24 + sizeof(*mmie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) mmie = (struct ieee80211_mmie *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) (skb->data + skb->len - sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (mmie->element_id != WLAN_EID_MMIE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) mmie->length != sizeof(*mmie) - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return RX_DROP_UNUSABLE; /* Invalid MMIE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) bip_ipn_swap(ipn, mmie->sequence_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) key->u.aes_cmac.replays++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (!(status->flag & RX_FLAG_DECRYPTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* hardware didn't decrypt/verify MIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) bip_aad(skb, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) skb->data + 24, skb->len - 24, mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) key->u.aes_cmac.icverrors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) memcpy(key->u.aes_cmac.rx_pn, ipn, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /* Remove MMIE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) skb_trim(skb, skb->len - sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct sk_buff *skb = rx->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct ieee80211_key *key = rx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct ieee80211_mmie_16 *mmie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) u8 aad[20], mic[16], ipn[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (!ieee80211_is_mgmt(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /* management frames are already linear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (skb->len < 24 + sizeof(*mmie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) mmie = (struct ieee80211_mmie_16 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) (skb->data + skb->len - sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (mmie->element_id != WLAN_EID_MMIE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) mmie->length != sizeof(*mmie) - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) return RX_DROP_UNUSABLE; /* Invalid MMIE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) bip_ipn_swap(ipn, mmie->sequence_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) key->u.aes_cmac.replays++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (!(status->flag & RX_FLAG_DECRYPTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /* hardware didn't decrypt/verify MIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) bip_aad(skb, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) skb->data + 24, skb->len - 24, mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) key->u.aes_cmac.icverrors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) memcpy(key->u.aes_cmac.rx_pn, ipn, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /* Remove MMIE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) skb_trim(skb, skb->len - sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct ieee80211_tx_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) struct ieee80211_key *key = tx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) struct ieee80211_mmie_16 *mmie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct ieee80211_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) u8 aad[GMAC_AAD_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) u64 pn64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) u8 nonce[GMAC_NONCE_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) skb = skb_peek(&tx->skbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) mmie = skb_put(skb, sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) mmie->element_id = WLAN_EID_MMIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) mmie->length = sizeof(*mmie) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) mmie->key_id = cpu_to_le16(key->conf.keyidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* PN = PN + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) pn64 = atomic64_inc_return(&key->conf.tx_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) bip_ipn_set64(mmie->sequence_number, pn64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) bip_aad(skb, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) memcpy(nonce, hdr->addr2, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) bip_ipn_swap(nonce + ETH_ALEN, mmie->sequence_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /* MIC = AES-GMAC(IGTK, AAD || Management Frame Body || MMIE, 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) skb->data + 24, skb->len - 24, mmie->mic) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) struct sk_buff *skb = rx->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) struct ieee80211_key *key = rx->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct ieee80211_mmie_16 *mmie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (!ieee80211_is_mgmt(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* management frames are already linear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (skb->len < 24 + sizeof(*mmie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) mmie = (struct ieee80211_mmie_16 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) (skb->data + skb->len - sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (mmie->element_id != WLAN_EID_MMIE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) mmie->length != sizeof(*mmie) - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return RX_DROP_UNUSABLE; /* Invalid MMIE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) bip_ipn_swap(ipn, mmie->sequence_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (memcmp(ipn, key->u.aes_gmac.rx_pn, 6) <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) key->u.aes_gmac.replays++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (!(status->flag & RX_FLAG_DECRYPTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) /* hardware didn't decrypt/verify MIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) bip_aad(skb, aad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) memcpy(nonce, hdr->addr2, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) memcpy(nonce + ETH_ALEN, ipn, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) mic = kmalloc(GMAC_MIC_LEN, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (!mic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) skb->data + 24, skb->len - 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) mic) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) key->u.aes_gmac.icverrors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) kfree(mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) kfree(mic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) memcpy(key->u.aes_gmac.rx_pn, ipn, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /* Remove MMIE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) skb_trim(skb, skb->len - sizeof(*mmie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) ieee80211_tx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) struct ieee80211_tx_info *info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ieee80211_tx_result res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) skb_queue_walk(&tx->skbs, skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) /* handle hw-only algorithm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (!info->control.hw_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return TX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (tx->key->flags & KEY_FLAG_CIPHER_SCHEME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) res = ieee80211_crypto_cs_encrypt(tx, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (res != TX_CONTINUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) ieee80211_tx_set_protected(tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) return TX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) ieee80211_rx_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (rx->sta && rx->sta->cipher_scheme)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return ieee80211_crypto_cs_decrypt(rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }