linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] staging:r8188eu: use lib80211 CCMP decrypt
@ 2018-02-23 14:57 Ivan Safonov
  2018-02-26  7:56 ` Dan Carpenter
  0 siblings, 1 reply; 4+ messages in thread
From: Ivan Safonov @ 2018-02-23 14:57 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, Hans de Goede, Janani Sankara Babu, linux-kernel, Ivan Safonov

Custom AES decrypt implementation replaced with lib80211 library.

Signed-off-by: Ivan Safonov <insafonov@gmail.com>
---
 drivers/staging/rtl8188eu/Kconfig             |   1 +
 drivers/staging/rtl8188eu/core/rtw_security.c | 266 +++++---------------------
 2 files changed, 51 insertions(+), 216 deletions(-)

diff --git a/drivers/staging/rtl8188eu/Kconfig b/drivers/staging/rtl8188eu/Kconfig
index d787a091d3c1..ff7832798a77 100644
--- a/drivers/staging/rtl8188eu/Kconfig
+++ b/drivers/staging/rtl8188eu/Kconfig
@@ -6,6 +6,7 @@ config R8188EU
 	select WEXT_PRIV
 	select LIB80211
 	select LIB80211_CRYPT_WEP
+	select LIB80211_CRYPT_CCMP
 	---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_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c
index 72da86fdd264..68e2c6790ee6 100644
--- a/drivers/staging/rtl8188eu/core/rtw_security.c
+++ b/drivers/staging/rtl8188eu/core/rtw_security.c
@@ -1275,217 +1275,24 @@ u32	rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
 		return res;
 }
 
-static int aes_decipher(u8 *key, uint	hdrlen,
-			u8 *pframe, uint plen)
+u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
 {
-	static u8	message[MAX_MSG_SIZE];
-	uint	qc_exists, a4_exists, i, j, payload_remainder,
-			num_blocks, payload_index;
-	int res = _SUCCESS;
-
-	u8 pn_vector[6];
-	u8 mic_iv[16];
-	u8 mic_header1[16];
-	u8 mic_header2[16];
-	u8 ctr_preload[16];
-
-	/* Intermediate Buffers */
-	u8 chain_buffer[16];
-	u8 aes_out[16];
-	u8 padded_buffer[16];
-	u8 mic[8];
-
-/*	uint	offset = 0; */
-	uint	frtype  = GetFrameType(pframe);
-	uint	frsubtype  = GetFrameSubType(pframe);
-	frsubtype >>= 4;
-
-	memset(mic_iv, 0, 16);
-	memset(mic_header1, 0, 16);
-	memset(mic_header2, 0, 16);
-	memset(ctr_preload, 0, 16);
-	memset(chain_buffer, 0, 16);
-	memset(aes_out, 0, 16);
-	memset(padded_buffer, 0, 16);
-
-	/* start to decrypt the payload */
-
-	num_blocks = (plen-8) / 16; /* plen including llc, payload_length and mic) */
-
-	payload_remainder = (plen-8) % 16;
-
-	pn_vector[0]  = pframe[hdrlen];
-	pn_vector[1]  = pframe[hdrlen+1];
-	pn_vector[2]  = pframe[hdrlen+4];
-	pn_vector[3]  = pframe[hdrlen+5];
-	pn_vector[4]  = pframe[hdrlen+6];
-	pn_vector[5]  = pframe[hdrlen+7];
-
-	if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen ==  WLAN_HDR_A3_QOS_LEN))
-		a4_exists = 0;
-	else
-		a4_exists = 1;
-
-	if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) ||
-	    (frtype == WIFI_DATA_CFACKPOLL)) {
-			qc_exists = 1;
-			if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
-				hdrlen += 2;
-	} else if ((frsubtype == 0x08) || (frsubtype == 0x09) ||
-		   (frsubtype == 0x0a) || (frsubtype == 0x0b)) {
-		if (hdrlen !=  WLAN_HDR_A3_QOS_LEN)
-			hdrlen += 2;
-		qc_exists = 1;
-	} else {
-		qc_exists = 0;
-	}
-
-	/*  now, decrypt pframe with hdrlen offset and plen long */
-
-	payload_index = hdrlen + 8; /*  8 is for extiv */
-
-	for (i = 0; i < num_blocks; i++) {
-		construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i+1);
-
-		aes128k128d(key, ctr_preload, aes_out);
-		bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
-
-		for (j = 0; j < 16; j++)
-			pframe[payload_index++] = chain_buffer[j];
-	}
-
-	if (payload_remainder > 0) {    /* If there is a short final block, then pad it,*/
-					/* encrypt it and copy the unpadded part back   */
-		construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks+1);
-
-		for (j = 0; j < 16; j++)
-			padded_buffer[j] = 0x00;
-		for (j = 0; j < payload_remainder; j++)
-			padded_buffer[j] = pframe[payload_index+j];
-		aes128k128d(key, ctr_preload, aes_out);
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		for (j = 0; j < payload_remainder; j++)
-			pframe[payload_index++] = chain_buffer[j];
-	}
-
-	/* start to calculate the mic */
-	if ((hdrlen+plen+8) <= MAX_MSG_SIZE)
-		memcpy(message, pframe, (hdrlen + plen+8)); /* 8 is for ext iv len */
-
-	pn_vector[0] = pframe[hdrlen];
-	pn_vector[1] = pframe[hdrlen+1];
-	pn_vector[2] = pframe[hdrlen+4];
-	pn_vector[3] = pframe[hdrlen+5];
-	pn_vector[4] = pframe[hdrlen+6];
-	pn_vector[5] = pframe[hdrlen+7];
-	construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen-8, pn_vector);
-
-	construct_mic_header1(mic_header1, hdrlen, message);
-	construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
-
-	payload_remainder = (plen-8) % 16;
-	num_blocks = (plen-8) / 16;
-
-	/* Find start of payload */
-	payload_index = hdrlen + 8;
-
-	/* Calculate MIC */
-	aes128k128d(key, mic_iv, aes_out);
-	bitwise_xor(aes_out, mic_header1, chain_buffer);
-	aes128k128d(key, chain_buffer, aes_out);
-	bitwise_xor(aes_out, mic_header2, chain_buffer);
-	aes128k128d(key, chain_buffer, aes_out);
-
-	for (i = 0; i < num_blocks; i++) {
-		bitwise_xor(aes_out, &message[payload_index], chain_buffer);
-
-		payload_index += 16;
-		aes128k128d(key, chain_buffer, aes_out);
-	}
-
-	/* Add on the final payload block if it needs padding */
-	if (payload_remainder > 0) {
-		for (j = 0; j < 16; j++)
-			padded_buffer[j] = 0x00;
-		for (j = 0; j < payload_remainder; j++)
-			padded_buffer[j] = message[payload_index++];
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		aes128k128d(key, chain_buffer, aes_out);
-	}
-
-	for (j = 0 ; j < 8; j++)
-		mic[j] = aes_out[j];
-
-	/* Insert MIC into payload */
-	for (j = 0; j < 8; j++)
-		message[payload_index+j] = mic[j];
-
-	payload_index = hdrlen + 8;
-	for (i = 0; i < num_blocks; i++) {
-		construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i+1);
-		aes128k128d(key, ctr_preload, aes_out);
-		bitwise_xor(aes_out, &message[payload_index], chain_buffer);
-		for (j = 0; j < 16; j++)
-			message[payload_index++] = chain_buffer[j];
-	}
-
-	if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/
-		/* encrypt it and copy the unpadded part back   */
-		construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, num_blocks+1);
-
-		for (j = 0; j < 16; j++)
-			padded_buffer[j] = 0x00;
-		for (j = 0; j < payload_remainder; j++)
-			padded_buffer[j] = message[payload_index+j];
-		aes128k128d(key, ctr_preload, aes_out);
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		for (j = 0; j < payload_remainder; j++)
-			message[payload_index++] = chain_buffer[j];
-	}
-
-	/* Encrypt the MIC */
-	construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, 0);
-
-	for (j = 0; j < 16; j++)
-		padded_buffer[j] = 0x00;
-	for (j = 0; j < 8; j++)
-		padded_buffer[j] = message[j+hdrlen+8+plen-8];
-
-	aes128k128d(key, ctr_preload, aes_out);
-	bitwise_xor(aes_out, padded_buffer, chain_buffer);
-	for (j = 0; j < 8; j++)
-		message[payload_index++] = chain_buffer[j];
-
-	/* compare the mic */
-	for (i = 0; i < 8; i++) {
-		if (pframe[hdrlen+8+plen-8+i] != message[hdrlen+8+plen-8+i]) {
-			RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
-				 ("aes_decipher:mic check error mic[%d]: pframe(%x)!=message(%x)\n",
-				 i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]));
-			DBG_88E("aes_decipher:mic check error mic[%d]: pframe(%x)!=message(%x)\n",
-				i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]);
-			res = _FAIL;
-		}
-	}
-	return res;
-}
-
-u32	rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
-{	/*  exclude ICV */
-	/* Intermediate Buffers */
-	int		length;
-	u8	*pframe, *prwskey;	/*  *payload,*iv */
-	struct	sta_info		*stainfo;
-	struct	rx_pkt_attrib	 *prxattrib = &((struct recv_frame *)precvframe)->attrib;
-	struct	security_priv	*psecuritypriv = &padapter->securitypriv;
-	u32	res = _SUCCESS;
+	struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib;
+	u32 res = _SUCCESS;
 
-	pframe = (unsigned char *)((struct recv_frame *)precvframe)->pkt->data;
 	/* 4 start to encrypt each fragment */
 	if (prxattrib->encrypt == _AES_) {
-		stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
+		struct sta_info *stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
+
 		if (stainfo != NULL) {
-			RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n"));
+			int key_idx;
+			const int key_length = 16, iv_len = 8, icv_len = 8;
+			struct sk_buff *skb = ((struct recv_frame *)precvframe)->pkt;
+			void *crypto_private = NULL;
+			u8 *key, *pframe = skb->data;
+			struct lib80211_crypto_ops *crypto_ops = try_then_request_module(lib80211_get_crypto_ops("CCMP"), "lib80211_crypt_ccmp");
+			struct security_priv *psecuritypriv = &padapter->securitypriv;
+			char iv[8], icv[8];
 
 			if (IS_MCAST(prxattrib->ra)) {
 				/* in concurrent we should use sw descrypt in group key, so we remove this message */
@@ -1494,18 +1301,45 @@ u32	rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
 					DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
 					goto exit;
 				}
-				prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
-				if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
-					DBG_88E("not match packet_index=%d, install_index=%d\n",
-						prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid);
-					res = _FAIL;
-					goto exit;
-				}
+				key_idx = psecuritypriv->dot118021XGrpKeyid;
+				key = psecuritypriv->dot118021XGrpKey[key_idx].skey;
 			} else {
-				prwskey = &stainfo->dot118021x_UncstKey.skey[0];
+				key_idx = 0;
+				key = stainfo->dot118021x_UncstKey.skey;
 			}
-			length = ((struct recv_frame *)precvframe)->pkt->len-prxattrib->hdrlen-prxattrib->iv_len;
-			res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
+
+			if (!crypto_ops) {
+				res = _FAIL;
+				goto exit_lib80211_ccmp;
+			}
+
+			memcpy(iv, pframe + prxattrib->hdrlen, iv_len);
+			memcpy(icv, pframe + skb->len - icv_len, icv_len);
+
+			crypto_private = crypto_ops->init(key_idx);
+			if (!crypto_private) {
+				res = _FAIL;
+				goto exit_lib80211_ccmp;
+			}
+			if (crypto_ops->set_key(key, key_length, NULL, crypto_private) < 0) {
+				res = _FAIL;
+				goto exit_lib80211_ccmp;
+			}
+			if (crypto_ops->decrypt_mpdu(skb, prxattrib->hdrlen, crypto_private)) {
+				res = _FAIL;
+				goto exit_lib80211_ccmp;
+			}
+
+			memmove(pframe, pframe + iv_len, prxattrib->hdrlen);
+			skb_push(skb, iv_len);
+			skb_put(skb, icv_len);
+
+			memcpy(pframe + prxattrib->hdrlen, iv, iv_len);
+			memcpy(pframe + skb->len - icv_len, icv, icv_len);
+
+exit_lib80211_ccmp:
+			if (crypto_ops && crypto_private)
+				crypto_ops->deinit(crypto_private);
 		} else {
 			RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo==NULL!!!\n"));
 			res = _FAIL;
-- 
2.16.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] staging:r8188eu: use lib80211 CCMP decrypt
  2018-02-23 14:57 [PATCH] staging:r8188eu: use lib80211 CCMP decrypt Ivan Safonov
@ 2018-02-26  7:56 ` Dan Carpenter
  2018-02-28  5:33   ` Ivan Safonov
  0 siblings, 1 reply; 4+ messages in thread
From: Dan Carpenter @ 2018-02-26  7:56 UTC (permalink / raw)
  To: Ivan Safonov
  Cc: devel, Greg Kroah-Hartman, Janani Sankara Babu, linux-kernel,
	Hans de Goede

On Fri, Feb 23, 2018 at 05:57:42PM +0300, Ivan Safonov wrote:
> Custom AES decrypt implementation replaced with lib80211 library.
> 
> Signed-off-by: Ivan Safonov <insafonov@gmail.com>

The new code looks like original RTL code (really bad) so I'm guessing
you copy and pasted the code from somewhere else?

The idea is good, but RTL code is painful to look at.

regards,
dan carpenter

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] staging:r8188eu: use lib80211 CCMP decrypt
  2018-02-26  7:56 ` Dan Carpenter
@ 2018-02-28  5:33   ` Ivan Safonov
  2018-02-28  6:40     ` Dan Carpenter
  0 siblings, 1 reply; 4+ messages in thread
From: Ivan Safonov @ 2018-02-28  5:33 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: devel, Greg Kroah-Hartman, Janani Sankara Babu, linux-kernel,
	Hans de Goede

On 02/26/2018 10:56 AM, Dan Carpenter wrote:
> On Fri, Feb 23, 2018 at 05:57:42PM +0300, Ivan Safonov wrote:
>> Custom AES decrypt implementation replaced with lib80211 library.
>>
>> Signed-off-by: Ivan Safonov <insafonov@gmail.com>
> 
> The new code looks like original RTL code (really bad) so I'm guessing
> you copy and pasted the code from somewhere else?
Unfortunately, your assumption is wrong. Rather, bad code is created 
because I'm not a good programmer =).

Seriously, after each patch the driver gets better, does not it?

> 
> The idea is good, but RTL code is painful to look at.
The basic idea is to replace a _small_ (or trivial) parts of the 
program, because I can not test my patches.

> 
> regards,
> dan carpenter
> 

Ivan Safonov.
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] staging:r8188eu: use lib80211 CCMP decrypt
  2018-02-28  5:33   ` Ivan Safonov
@ 2018-02-28  6:40     ` Dan Carpenter
  0 siblings, 0 replies; 4+ messages in thread
From: Dan Carpenter @ 2018-02-28  6:40 UTC (permalink / raw)
  To: Ivan Safonov
  Cc: devel, Greg Kroah-Hartman, Janani Sankara Babu, linux-kernel,
	Hans de Goede

Hm...  Sorry.  I was looking at the wrong code.

I was looking at aes_decipher() instead of rtw_aes_decrypt().  The
aes_decipher() was acceptable style (although, it's of course good that
you deleted it).  rtw_aes_decrypt() was always really really awful.

That's fine then.  Sorry again.

regards,
dan carpenter

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-02-28  6:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-23 14:57 [PATCH] staging:r8188eu: use lib80211 CCMP decrypt Ivan Safonov
2018-02-26  7:56 ` Dan Carpenter
2018-02-28  5:33   ` Ivan Safonov
2018-02-28  6:40     ` Dan Carpenter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).