staging:r8188eu: Use lib80211 to decrypt WEP-frames
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>
This commit is contained in:
parent
fd161c6198
commit
2b2ea09e74
@ -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,
|
|||||||
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 @@
|
|||||||
#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)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
pframe = (unsigned char *)((struct recv_frame *)precvframe)->pkt->data;
|
|
||||||
|
|
||||||
/* start to decrypt recvframe */
|
|
||||||
if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
|
if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
|
||||||
iv = pframe+prxattrib->hdrlen;
|
struct security_priv *psecuritypriv = &padapter->securitypriv;
|
||||||
keyindex = prxattrib->key_index;
|
struct sk_buff *skb = ((struct recv_frame *)precvframe)->pkt;
|
||||||
keylength = psecuritypriv->dot11DefKeylen[keyindex];
|
u8 *pframe = skb->data;
|
||||||
memcpy(&wepkey[0], iv, 3);
|
void *crypto_private = NULL;
|
||||||
memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
|
int status = _SUCCESS;
|
||||||
length = ((struct recv_frame *)precvframe)->pkt->len-prxattrib->hdrlen-prxattrib->iv_len;
|
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];
|
||||||
|
|
||||||
payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
|
if (!crypto_ops) {
|
||||||
|
status = _FAIL;
|
||||||
/* decrypt payload include icv */
|
goto exit;
|
||||||
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]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(iv, pframe + prxattrib->hdrlen, 4);
|
||||||
|
memcpy(icv, pframe + skb->len - 4, 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 ===== */
|
/* 3 ===== TKIP related ===== */
|
||||||
|
@ -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_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user