From 2ba8444c97b1ff72a80219d9baeec5e75995c926 Mon Sep 17 00:00:00 2001 From: Ivan Safonov Date: Tue, 2 May 2017 09:01:39 +0300 Subject: [PATCH] staging:r8188eu: move IV/ICV trimming into decrypt() and also place it after rtl88eu_mon_recv_hook() IV/ICV should be trimmed immediately after decoding (this is a decryptor job). Trim IV/ICV inside decrypt() for SW decrypted frames, for HW decrypted - before rtl88eu_mon_recv_hook(). Adopt frames receive process to work without IV/ICV fields. Signed-off-by: Ivan Safonov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_recv.c | 80 ++++++++++++------------------- 1 file changed, 30 insertions(+), 50 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index c6c4404..e8f0ff9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -259,12 +259,10 @@ static int recvframe_chkmic(struct adapter *adapter, } /* icv_len included the mic code */ - datalen = precvframe->pkt->len-prxattrib->hdrlen - - prxattrib->iv_len-prxattrib->icv_len-8; + datalen = precvframe->pkt->len-prxattrib->hdrlen - 8; pframe = precvframe->pkt->data; - payload = pframe+prxattrib->hdrlen+prxattrib->iv_len; + payload = pframe+prxattrib->hdrlen; - RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n prxattrib->iv_len=%d prxattrib->icv_len=%d\n", prxattrib->iv_len, prxattrib->icv_len)); rtw_seccalctkipmic(mickey, pframe, payload, datalen, &miccode[0], (unsigned char)prxattrib->priority); /* care the length of the data */ @@ -409,9 +407,15 @@ static struct recv_frame *decryptor(struct adapter *padapter, default: break; } + if (res != _FAIL) { + memmove(precv_frame->pkt->data + precv_frame->attrib.iv_len, precv_frame->pkt->data, precv_frame->attrib.hdrlen); + skb_pull(precv_frame->pkt, precv_frame->attrib.iv_len); + skb_trim(precv_frame->pkt, precv_frame->pkt->len - precv_frame->attrib.icv_len); + } } else if (prxattrib->bdecrypted == 1 && prxattrib->encrypt > 0 && - (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)) - psecuritypriv->hw_decrypted = true; + (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)) { + psecuritypriv->hw_decrypted = true; + } if (res == _FAIL) { rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue); @@ -452,7 +456,7 @@ static struct recv_frame *portctrl(struct adapter *adapter, if (auth_alg == 2) { /* get ether_type */ - ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE + pfhdr->attrib.iv_len; + ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; memcpy(&be_tmp, ptr, 2); ether_type = ntohs(be_tmp); @@ -1263,6 +1267,13 @@ static int validate_recv_frame(struct adapter *adapter, */ rtl88eu_mon_recv_hook(adapter->pmondev, precv_frame); + if (precv_frame->attrib.bdecrypted == 1 && precv_frame->attrib.encrypt > 0 && + (adapter->securitypriv.busetkipkey == 1 || precv_frame->attrib.encrypt != _TKIP_)) { + memmove(precv_frame->pkt->data + precv_frame->attrib.iv_len, precv_frame->pkt->data, precv_frame->attrib.hdrlen); + skb_pull(precv_frame->pkt, precv_frame->attrib.iv_len); + skb_trim(precv_frame->pkt, precv_frame->pkt->len - precv_frame->attrib.icv_len); + } + exit: return retval; @@ -1282,11 +1293,8 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) u8 *ptr = precvframe->pkt->data; struct rx_pkt_attrib *pattrib = &precvframe->attrib; - if (pattrib->encrypt) - skb_trim(precvframe->pkt, precvframe->pkt->len - pattrib->icv_len); - - psnap = (struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen + pattrib->iv_len); - psnap_type = ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; + psnap = (struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen); + psnap_type = ptr+pattrib->hdrlen + SNAP_SIZE; /* convert hdr + possible LLC headers into Ethernet header */ if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && (!memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == false) && @@ -1299,12 +1307,9 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) bsnaphdr = false; } - rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0); + rmv_len = pattrib->hdrlen + (bsnaphdr ? SNAP_SIZE : 0); len = precvframe->pkt->len - rmv_len; - RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, - ("\n===pattrib->hdrlen: %x, pattrib->iv_len:%x===\n\n", pattrib->hdrlen, pattrib->iv_len)); - memcpy(&be_tmp, ptr+rmv_len, 2); eth_type = ntohs(be_tmp); /* pattrib->ether_type */ pattrib->eth_type = eth_type; @@ -1329,7 +1334,6 @@ static struct recv_frame *recvframe_defrag(struct adapter *adapter, struct __queue *defrag_q) { struct list_head *plist, *phead; - u8 wlanhdr_offset; u8 curfragnum; struct recv_frame *pfhdr, *pnfhdr; struct recv_frame *prframe, *pnextrframe; @@ -1378,12 +1382,7 @@ static struct recv_frame *recvframe_defrag(struct adapter *adapter, /* copy the 2nd~n fragment frame's payload to the first fragment */ /* get the 2nd~last fragment frame's payload */ - wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; - - skb_pull(pnextrframe->pkt, wlanhdr_offset); - - /* append to first fragment frame's tail (if privacy frame, pull the ICV) */ - skb_trim(prframe->pkt, prframe->pkt->len - pfhdr->attrib.icv_len); + skb_pull(pnextrframe->pkt, pnfhdr->attrib.hdrlen); /* memcpy */ memcpy(skb_tail_pointer(pfhdr->pkt), pnfhdr->pkt->data, @@ -1391,7 +1390,7 @@ static struct recv_frame *recvframe_defrag(struct adapter *adapter, skb_put(prframe->pkt, pnfhdr->pkt->len); - pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len; + pfhdr->attrib.icv_len = 0; plist = plist->next; } @@ -1518,11 +1517,6 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) nr_subframes = 0; pattrib = &prframe->attrib; - skb_pull(prframe->pkt, prframe->attrib.hdrlen); - - if (prframe->attrib.iv_len > 0) - skb_pull(prframe->pkt, prframe->attrib.iv_len); - a_len = prframe->pkt->len; pdata = prframe->pkt->data; @@ -1892,24 +1886,6 @@ static int process_recv_indicatepkts(struct adapter *padapter, return retval; } -static int recv_func_prehandle(struct adapter *padapter, - struct recv_frame *rframe) -{ - int ret = _SUCCESS; - struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; - - /* check the frame crtl field and decache */ - ret = validate_recv_frame(padapter, rframe); - if (ret != _SUCCESS) { - RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n")); - rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ - goto exit; - } - -exit: - return ret; -} - static int recv_func_posthandle(struct adapter *padapter, struct recv_frame *prframe) { @@ -1962,6 +1938,7 @@ static int recv_func(struct adapter *padapter, struct recv_frame *rframe) struct rx_pkt_attrib *prxattrib = &rframe->attrib; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; /* check if need to handle uc_swdec_pending_queue*/ if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) { @@ -1973,9 +1950,12 @@ static int recv_func(struct adapter *padapter, struct recv_frame *rframe) } } - ret = recv_func_prehandle(padapter, rframe); - - if (ret == _SUCCESS) { + /* check the frame crtl field and decache */ + ret = validate_recv_frame(padapter, rframe); + if (ret != _SUCCESS) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n")); + rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ + } else { /* check if need to enqueue into uc_swdec_pending_queue*/ if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && !IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 && -- 2.7.4