Commit 2b2ea09e authored by Ivan Safonov's avatar Ivan Safonov Committed by Greg Kroah-Hartman

staging:r8188eu: Use lib80211 to decrypt WEP-frames

Use native lib80211 WEP decrypt instead of custom implementation.
Signed-off-by: default avatarIvan Safonov <insafonov@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fd161c61
...@@ -4,6 +4,8 @@ config R8188EU ...@@ -4,6 +4,8 @@ config R8188EU
depends on m depends on m
select WIRELESS_EXT select WIRELESS_EXT
select WEXT_PRIV select WEXT_PRIV
select LIB80211
select LIB80211_CRYPT_WEP
---help--- ---help---
This option adds the Realtek RTL8188EU USB device such as TP-Link TL-WN725N. This option adds the Realtek RTL8188EU USB device such as TP-Link TL-WN725N.
If built as a module, it will be called r8188eu. If built as a module, it will be called r8188eu.
......
...@@ -404,7 +404,7 @@ static struct recv_frame *decryptor(struct adapter *padapter, ...@@ -404,7 +404,7 @@ static struct recv_frame *decryptor(struct adapter *padapter,
switch (prxattrib->encrypt) { switch (prxattrib->encrypt) {
case _WEP40_: case _WEP40_:
case _WEP104_: case _WEP104_:
rtw_wep_decrypt(padapter, (u8 *)precv_frame); res = rtw_wep_decrypt(padapter, (u8 *)precv_frame);
break; break;
case _TKIP_: case _TKIP_:
res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame); res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <drv_types.h> #include <drv_types.h>
#include <wifi.h> #include <wifi.h>
#include <osdep_intf.h> #include <osdep_intf.h>
#include <net/lib80211.h>
/* WEP related ===== */ /* WEP related ===== */
...@@ -195,48 +196,57 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe) ...@@ -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 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 */ crypto_private = crypto_ops->init(keyindex);
if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) { if (!crypto_private) {
iv = pframe+prxattrib->hdrlen; status = _FAIL;
keyindex = prxattrib->key_index; goto exit;
keylength = psecuritypriv->dot11DefKeylen[keyindex]; }
memcpy(&wepkey[0], iv, 3); if (crypto_ops->set_key(psecuritypriv->dot11DefKey[keyindex].skey,
memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength); psecuritypriv->dot11DefKeylen[keyindex], NULL, crypto_private) < 0) {
length = ((struct recv_frame *)precvframe)->pkt->len-prxattrib->hdrlen-prxattrib->iv_len; status = _FAIL;
goto exit;
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]));
} }
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 ===== */ /* 3 ===== TKIP related ===== */
......
...@@ -308,6 +308,6 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe); ...@@ -308,6 +308,6 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe);
void rtw_wep_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_aes_decrypt(struct adapter *padapter, u8 *precvframe);
u32 rtw_tkip_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_ */ #endif /* __RTL871X_SECURITY_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment