Received: by 10.223.185.116 with SMTP id b49csp794628wrg; Fri, 23 Feb 2018 06:58:41 -0800 (PST) X-Google-Smtp-Source: AH8x227FNnTVZxeldSANcVgJ3NpLnpjn1oNObiHtg5lS+mzpTUZKCIHbw4r25fdMLHya0TfbRPtT X-Received: by 2002:a17:902:1683:: with SMTP id h3-v6mr1997255plh.433.1519397921636; Fri, 23 Feb 2018 06:58:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519397921; cv=none; d=google.com; s=arc-20160816; b=ulb9+ISsWpfcH4jvSkTQ06q7dew6X2baE3qJoqar7pdFbKg17DNKFjjGacSWckMDgp RgJ0QNd4vghN1tNHfpFecYpBFqNqcqP3shuP9EBm51AJLzTd3wz6BYrYOJB5CG79rHB6 32kstGyE7jIApeyQ4ReCKE4ObAUSHQNAtCOp4W5dGD43BQXX6m/5Hp3IZ18+/RFz5VAq nSi3ABB9hoacqnvv/CnucX3XlL38vGUq1ZMgipdGcqdDBkTP18r5YrazsD+hOrdyps9j I5RxzXsp/XPlnsrcfWPf0XkW/GU/d3rD0iSrlf34RAaW+fynUfXF9UtCRVpqoxYo9EpD FppQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=3AUYCeKu0GEW4WPkfYM5T52UAynIMMzKc+aVHj2EXs0=; b=tOBWk/IbZ3Qi8ghx9nWA+37BOIHI61Iz2y5KN0nOYxP+pp2WFKz5J+L3wWxc2GMpXl DMFR8ocgOBkylfEh6twbQSRDNlgThbNUDFlg81/aQZTSiIQTPa8n7Wdp1cOUShbyCB0w I41OzJo+VRhRk77zhNT0qns2kDd4d34fDrk5+ktD65+ATu9xsDs4kSuhDVr4DJw5Zns8 5H7doIDbUq5gMvY5f4zmN8ecsan6fsvg2IdLF3AdjpGbsUo+QQIYduqibyzhvMqaj2mS NlBh0bVQ0XsU1nUcjcTK6vt+IJrZsjP9FkGeOx2KIYItpt8nzRGDwTHn1EIRS+jr0fcn duSA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=IDSaQPTA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h34-v6si1905766pld.26.2018.02.23.06.58.27; Fri, 23 Feb 2018 06:58:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=IDSaQPTA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751797AbeBWO51 (ORCPT + 99 others); Fri, 23 Feb 2018 09:57:27 -0500 Received: from mail-lf0-f68.google.com ([209.85.215.68]:45588 "EHLO mail-lf0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751699AbeBWO5Y (ORCPT ); Fri, 23 Feb 2018 09:57:24 -0500 Received: by mail-lf0-f68.google.com with SMTP id x196so12724811lfd.12 for ; Fri, 23 Feb 2018 06:57:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=3AUYCeKu0GEW4WPkfYM5T52UAynIMMzKc+aVHj2EXs0=; b=IDSaQPTAgMt4N3+mNYGgPxaAoKUaVdJ9x0S5hDDBKkTladJPmEF3NtYtysrtS6X+72 h1HfTi188iJVQEDYnjgNWMWv8t8rKgl224jtW9hxMCmRYYkEcEnj4Md7f6Jw6OrHvToy klamXfsbHqO2ef/iNb97A5vQjAgyvgfPhgXBYMrGVdnD8WX2cxMc8EPzd/Q5TfvFqMIC /qfIWoTztbOc/HOwTZuShh69is/PukZo1ZNzcJCeLFMdie/hAlE5SYWFA6HUpfd7KiBs e+LRHTA33k1AQKaoqvhFLA6NI3MvC1ogk73O00nQbbFC1tmPBac3aAgQaBmUOplky3wo pEMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=3AUYCeKu0GEW4WPkfYM5T52UAynIMMzKc+aVHj2EXs0=; b=mFuIp/PH/F6cswZV8/Qr7muOK+mRfGJUkhbeXL8iLkSG5j5Hjd0sc8rF+zoc/+PAOh 9ljLLKBUHzA0dPqY+SYdOtva/K4wl4AkJbRHzmE+YtTldC+wKGU+pymfIkXcBaAlKeBD YsAAkA4bkGzQLEwfrAnnu9CfMO1gvI7/SqvBRrsA5NwjtsO3u6Zcv7Yj3IG5D6ULTst5 DZfCJw2uLzyIftkv3YpzkAJb4vKTT5fGIuQM+Kx1KsSR1r9pCMSYHSa54a+B79tMT3by 51gWDhPVMX35KzBluaRSNyKtvhh0wRu/4toDG9/cCBVOxcD0226O2CpQWIBtEmBGL2jx S4nw== X-Gm-Message-State: APf1xPD8L87ByUM+DA0sjPi9id5hwMG3JlgiHnz4sUmLsMQXu6DTZS/z PfZOZ2zUAsn93DelRbmuL2op9A== X-Received: by 10.46.20.30 with SMTP id u30mr1627659ljd.12.1519397842267; Fri, 23 Feb 2018 06:57:22 -0800 (PST) Received: from alpha (92-100-183-179.dynamic.avangarddsl.ru. [92.100.183.179]) by smtp.gmail.com with ESMTPSA id c74sm503319lfe.96.2018.02.23.06.57.21 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 23 Feb 2018 06:57:21 -0800 (PST) Received: (nullmailer pid 25831 invoked by uid 1000); Fri, 23 Feb 2018 14:58:03 -0000 From: Ivan Safonov To: Greg Kroah-Hartman Cc: Hans de Goede , Janani Sankara Babu , devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, Ivan Safonov Subject: [PATCH] staging:r8188eu: use lib80211 CCMP decrypt Date: Fri, 23 Feb 2018 17:57:42 +0300 Message-Id: <20180223145742.25783-1-insafonov@gmail.com> X-Mailer: git-send-email 2.16.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Custom AES decrypt implementation replaced with lib80211 library. Signed-off-by: Ivan Safonov --- 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