Skip to content

Commit

Permalink
staging:r8188eu: Use lib80211 to decrypt WEP-frames
Browse files Browse the repository at this point in the history
Use native lib80211 WEP decrypt instead of custom implementation.

Signed-off-by: Ivan Safonov <insafonov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Ivan Safonov authored and Greg Kroah-Hartman committed Feb 19, 2018
1 parent fd161c6 commit 2b2ea09
Showing 4 changed files with 49 additions and 37 deletions.
2 changes: 2 additions & 0 deletions drivers/staging/rtl8188eu/Kconfig
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@ config R8188EU
depends on m
select WIRELESS_EXT
select WEXT_PRIV
select LIB80211
select LIB80211_CRYPT_WEP
---help---
This option adds the Realtek RTL8188EU USB device such as TP-Link TL-WN725N.
If built as a module, it will be called r8188eu.
2 changes: 1 addition & 1 deletion drivers/staging/rtl8188eu/core/rtw_recv.c
Original file line number Diff line number Diff line change
@@ -404,7 +404,7 @@ static struct recv_frame *decryptor(struct adapter *padapter,
switch (prxattrib->encrypt) {
case _WEP40_:
case _WEP104_:
rtw_wep_decrypt(padapter, (u8 *)precv_frame);
res = rtw_wep_decrypt(padapter, (u8 *)precv_frame);
break;
case _TKIP_:
res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
80 changes: 45 additions & 35 deletions drivers/staging/rtl8188eu/core/rtw_security.c
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
#include <drv_types.h>
#include <wifi.h>
#include <osdep_intf.h>
#include <net/lib80211.h>

/* WEP related ===== */

@@ -195,48 +196,57 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)

}

void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
int rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
{
/* exclude ICV */
u8 crc[4];
struct arc4context mycontext;
int length;
u32 keylength;
u8 *pframe, *payload, *iv, wepkey[16];
u8 keyindex;
struct rx_pkt_attrib *prxattrib = &(((struct recv_frame *)precvframe)->attrib);
struct security_priv *psecuritypriv = &padapter->securitypriv;

if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
struct security_priv *psecuritypriv = &padapter->securitypriv;
struct sk_buff *skb = ((struct recv_frame *)precvframe)->pkt;
u8 *pframe = skb->data;
void *crypto_private = NULL;
int status = _SUCCESS;
const int keyindex = prxattrib->key_index;
struct lib80211_crypto_ops *crypto_ops = try_then_request_module(lib80211_get_crypto_ops("WEP"), "lib80211_crypt_wep");
char iv[4], icv[4];

if (!crypto_ops) {
status = _FAIL;
goto exit;
}

pframe = (unsigned char *)((struct recv_frame *)precvframe)->pkt->data;
memcpy(iv, pframe + prxattrib->hdrlen, 4);
memcpy(icv, pframe + skb->len - 4, 4);

/* start to decrypt recvframe */
if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
iv = pframe+prxattrib->hdrlen;
keyindex = prxattrib->key_index;
keylength = psecuritypriv->dot11DefKeylen[keyindex];
memcpy(&wepkey[0], iv, 3);
memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
length = ((struct recv_frame *)precvframe)->pkt->len-prxattrib->hdrlen-prxattrib->iv_len;

payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;

/* decrypt payload include icv */
arcfour_init(&mycontext, wepkey, 3+keylength);
arcfour_encrypt(&mycontext, payload, payload, length);

/* calculate icv and compare the icv */
*((__le32 *)crc) = getcrc32(payload, length - 4);

if (crc[3] != payload[length-1] ||
crc[2] != payload[length-2] ||
crc[1] != payload[length-3] ||
crc[0] != payload[length-4]) {
RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
("rtw_wep_decrypt:icv error crc (%4ph)!=payload (%4ph)\n",
&crc, &payload[length-4]));
crypto_private = crypto_ops->init(keyindex);
if (!crypto_private) {
status = _FAIL;
goto exit;
}
if (crypto_ops->set_key(psecuritypriv->dot11DefKey[keyindex].skey,
psecuritypriv->dot11DefKeylen[keyindex], NULL, crypto_private) < 0) {
status = _FAIL;
goto exit;
}
if (crypto_ops->decrypt_mpdu(skb, prxattrib->hdrlen, crypto_private)) {
status = _FAIL;
goto exit;
}

memmove(pframe, pframe + 4, prxattrib->hdrlen);
skb_push(skb, 4);
skb_put(skb, 4);

memcpy(pframe + prxattrib->hdrlen, iv, 4);
memcpy(pframe + skb->len - 4, icv, 4);

exit:
if (crypto_ops && crypto_private)
crypto_ops->deinit(crypto_private);
return status;
}

return _FAIL;
}

/* 3 ===== TKIP related ===== */
2 changes: 1 addition & 1 deletion drivers/staging/rtl8188eu/include/rtw_security.h
Original file line number Diff line number Diff line change
@@ -308,6 +308,6 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe);
void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe);
u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe);
u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe);
void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe);
int rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe);

#endif /* __RTL871X_SECURITY_H_ */

0 comments on commit 2b2ea09

Please sign in to comment.