From 10e4d4a858ba7a2d06edfec388d01023a5503a8e Mon Sep 17 00:00:00 2001 From: psimha Date: Wed, 14 Feb 2018 07:19:51 -0800 Subject: [PATCH] qcacmn: Fixes for AES-CCMP, WEP encrypted fragments Account for encryption header size during 802.11 header decapsulation. Change-Id: I7c0f75ffc2cd2790bfb06a685e9e7612c59e485d CRs-Fixed: 2171371 --- dp/wifi3.0/dp_rx_defrag.c | 43 +++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index 52b5a3df3d85..c6d3f5b283a2 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/dp/wifi3.0/dp_rx_defrag.c @@ -398,8 +398,7 @@ static QDF_STATUS dp_rx_defrag_ccmp_decap(qdf_nbuf_t nbuf, uint16_t hdrlen) if (!(ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV)) return QDF_STATUS_E_DEFRAG_ERROR; - qdf_mem_move(origHdr + dp_f_ccmp.ic_header, origHdr, hdrlen); - qdf_nbuf_pull_head(nbuf, dp_f_ccmp.ic_header); + /* Let's pull the header later */ return QDF_STATUS_SUCCESS; } @@ -421,7 +420,6 @@ static QDF_STATUS dp_rx_defrag_wep_decap(qdf_nbuf_t msdu, uint16_t hdrlen) origHdr = (uint8_t *) (qdf_nbuf_data(msdu) + rx_desc_len); qdf_mem_move(origHdr + dp_f_wep.ic_header, origHdr, hdrlen); - qdf_nbuf_pull_head(msdu, dp_f_wep.ic_header); qdf_nbuf_trim_tail(msdu, dp_f_wep.ic_trailer); return QDF_STATUS_SUCCESS; @@ -689,15 +687,14 @@ static QDF_STATUS dp_rx_defrag_tkip_demic(const uint8_t *key, /* * dp_rx_frag_pull_hdr(): Pulls the RXTLV & the 802.11 headers * @nbuf: buffer pointer + * @hdrsize: size of the header to be pulled * * Pull the RXTLV & the 802.11 headers * * Returns: None */ -static void dp_rx_frag_pull_hdr(qdf_nbuf_t nbuf) +static void dp_rx_frag_pull_hdr(qdf_nbuf_t nbuf, uint16_t hdrsize) { - uint16_t hdrsize = dp_rx_defrag_hdrsize(nbuf); - qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN + hdrsize); @@ -711,20 +708,22 @@ static void dp_rx_frag_pull_hdr(qdf_nbuf_t nbuf) * dp_rx_construct_fraglist(): Construct a nbuf fraglist * @peer: Pointer to the peer * @head: Pointer to list of fragments + * @hdrsize: Size of the header to be pulled * * Construct a nbuf fraglist * * Returns: None */ static void -dp_rx_construct_fraglist(struct dp_peer *peer, qdf_nbuf_t head) +dp_rx_construct_fraglist(struct dp_peer *peer, + qdf_nbuf_t head, uint16_t hdrsize) { qdf_nbuf_t msdu = qdf_nbuf_next(head); qdf_nbuf_t rx_nbuf = msdu; uint32_t len = 0; while (msdu) { - dp_rx_frag_pull_hdr(msdu); + dp_rx_frag_pull_hdr(msdu, hdrsize); len += qdf_nbuf_len(msdu); msdu = qdf_nbuf_next(msdu); } @@ -767,14 +766,15 @@ static void dp_rx_defrag_err(uint8_t vdev_id, uint8_t *peer_mac_addr, /* * dp_rx_defrag_nwifi_to_8023(): Transcap 802.11 to 802.3 * @nbuf: Pointer to the fragment buffer + * @hdrsize: Size of headers * * Transcap the fragment from 802.11 to 802.3 * * Returns: None */ -static void dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf) +static void +dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf, uint16_t hdrsize) { - uint32_t hdrsize; struct llc_snap_hdr_t *llchdr; struct ethernet_hdr_t *eth_hdr; uint8_t ether_type[2]; @@ -789,8 +789,6 @@ static void dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf) return; } - hdrsize = dp_rx_defrag_hdrsize(nbuf); - qdf_mem_copy(rx_desc_info, qdf_nbuf_data(nbuf), RX_PKT_TLVS_LEN); llchdr = (struct llc_snap_hdr_t *)(qdf_nbuf_data(nbuf) + @@ -1065,10 +1063,15 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid, qdf_nbuf_set_next(cur, tmp_next); cur = tmp_next; } + cur = frag_list_head; - /* Temporary fix to drop all encrypted packets */ - if (peer->security[index].sec_type != - htt_sec_type_none) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, + "%s: Security type: %d\n", __func__, + peer->security[index].sec_type); + + /* Temporary fix to drop TKIP encrypted packets */ + if (peer->security[index].sec_type == + htt_sec_type_tkip) { return QDF_STATUS_E_DEFRAG_ERROR; } @@ -1121,6 +1124,9 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid, } cur = tmp_next; } + + /* If success, increment header to be stripped later */ + hdr_space += dp_f_ccmp.ic_header; break; case htt_sec_type_wep40: case htt_sec_type_wep104: @@ -1140,6 +1146,9 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid, } cur = tmp_next; } + + /* If success, increment header to be stripped later */ + hdr_space += dp_f_wep.ic_header; break; default: QDF_TRACE(QDF_MODULE_ID_TXRX, @@ -1166,8 +1175,8 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid, } /* Convert the header to 802.3 header */ - dp_rx_defrag_nwifi_to_8023(frag_list_head); - dp_rx_construct_fraglist(peer, frag_list_head); + dp_rx_defrag_nwifi_to_8023(frag_list_head, hdr_space); + dp_rx_construct_fraglist(peer, frag_list_head, hdr_space); return QDF_STATUS_SUCCESS; }