[PATCH] staging:r8188eu: Use lib80211 to decrypt WEP-frames

2018-02-18 Thread Ivan Safonov
Use native lib80211 WEP decrypt instead of custom implementation.

Signed-off-by: Ivan Safonov 
---
 drivers/staging/rtl8188eu/Kconfig|  2 +
 drivers/staging/rtl8188eu/core/rtw_recv.c|  2 +-
 drivers/staging/rtl8188eu/core/rtw_security.c| 80 +---
 drivers/staging/rtl8188eu/include/rtw_security.h |  2 +-
 4 files changed, 49 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/rtl8188eu/Kconfig 
b/drivers/staging/rtl8188eu/Kconfig
index cb836c59d564..d787a091d3c1 100644
--- a/drivers/staging/rtl8188eu/Kconfig
+++ b/drivers/staging/rtl8188eu/Kconfig
@@ -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.
diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c 
b/drivers/staging/rtl8188eu/core/rtw_recv.c
index 6506a1587df0..fe31ebbf36fb 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -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);
diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c 
b/drivers/staging/rtl8188eu/core/rtw_security.c
index 5b1ef229df2a..72da86fdd264 100644
--- a/drivers/staging/rtl8188eu/core/rtw_security.c
+++ b/drivers/staging/rtl8188eu/core/rtw_security.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* 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 = >securitypriv;
 
+   if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == 
_WEP104_)) {
+   struct  security_priv   *psecuritypriv = 
>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([0], iv, 3);
-   memcpy([3], 
>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(, wepkey, 3+keylength);
-   arcfour_encrypt(, 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",
-, [length-4]));
+   crypto_private = crypto_ops->init(keyindex);
+   if (!crypto_private) {
+   status = _FAIL;
+   goto 

[PATCH] staging:r8188eu: Use lib80211 to decrypt WEP-frames

2018-02-18 Thread Ivan Safonov
Use native lib80211 WEP decrypt instead of custom implementation.

Signed-off-by: Ivan Safonov 
---
 drivers/staging/rtl8188eu/Kconfig|  2 +
 drivers/staging/rtl8188eu/core/rtw_recv.c|  2 +-
 drivers/staging/rtl8188eu/core/rtw_security.c| 80 +---
 drivers/staging/rtl8188eu/include/rtw_security.h |  2 +-
 4 files changed, 49 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/rtl8188eu/Kconfig 
b/drivers/staging/rtl8188eu/Kconfig
index cb836c59d564..d787a091d3c1 100644
--- a/drivers/staging/rtl8188eu/Kconfig
+++ b/drivers/staging/rtl8188eu/Kconfig
@@ -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.
diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c 
b/drivers/staging/rtl8188eu/core/rtw_recv.c
index 6506a1587df0..fe31ebbf36fb 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -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);
diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c 
b/drivers/staging/rtl8188eu/core/rtw_security.c
index 5b1ef229df2a..72da86fdd264 100644
--- a/drivers/staging/rtl8188eu/core/rtw_security.c
+++ b/drivers/staging/rtl8188eu/core/rtw_security.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* 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 = >securitypriv;
 
+   if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == 
_WEP104_)) {
+   struct  security_priv   *psecuritypriv = 
>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([0], iv, 3);
-   memcpy([3], 
>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(, wepkey, 3+keylength);
-   arcfour_encrypt(, 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",
-, [length-4]));
+   crypto_private = crypto_ops->init(keyindex);
+   if (!crypto_private) {
+   status = _FAIL;
+   goto exit;
+   }