mac80211: update to wireless-testing 2017-11-01
The wireless regdb is now loaded via firmware loading, CRDA support and built-in regdb support have been removed. Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
		@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
PKG_NAME:=mac80211
 | 
					PKG_NAME:=mac80211
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PKG_VERSION:=2017-10-06
 | 
					PKG_VERSION:=2017-11-01
 | 
				
			||||||
PKG_RELEASE:=1
 | 
					PKG_RELEASE:=1
 | 
				
			||||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 | 
					PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 | 
				
			||||||
PKG_HASH:=194786b7635f36b9ce280fd2319f6a4feeff209175e330ddbcbe789a3b4540a5
 | 
					PKG_HASH:=8437ab7886b988c8152e7a4db30b7f41009e49a3b2cb863edd05da1ecd7eb05a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
 | 
					PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
 | 
				
			||||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
 | 
					PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
 | 
				
			||||||
@@ -87,7 +87,7 @@ endef
 | 
				
			|||||||
define KernelPackage/cfg80211
 | 
					define KernelPackage/cfg80211
 | 
				
			||||||
  $(call KernelPackage/mac80211/Default)
 | 
					  $(call KernelPackage/mac80211/Default)
 | 
				
			||||||
  TITLE:=cfg80211 - wireless configuration API
 | 
					  TITLE:=cfg80211 - wireless configuration API
 | 
				
			||||||
  DEPENDS+= +iw
 | 
					  DEPENDS+= +iw +wireless-regdb
 | 
				
			||||||
  FILES:= \
 | 
					  FILES:= \
 | 
				
			||||||
	$(PKG_BUILD_DIR)/compat/compat.ko \
 | 
						$(PKG_BUILD_DIR)/compat/compat.ko \
 | 
				
			||||||
	$(PKG_BUILD_DIR)/net/wireless/cfg80211.ko
 | 
						$(PKG_BUILD_DIR)/net/wireless/cfg80211.ko
 | 
				
			||||||
@@ -1516,7 +1516,6 @@ config-y:= \
 | 
				
			|||||||
	WLAN \
 | 
						WLAN \
 | 
				
			||||||
	NL80211_TESTMODE \
 | 
						NL80211_TESTMODE \
 | 
				
			||||||
	CFG80211_WEXT \
 | 
						CFG80211_WEXT \
 | 
				
			||||||
	CFG80211_INTERNAL_REGDB \
 | 
					 | 
				
			||||||
	CFG80211_CERTIFICATION_ONUS \
 | 
						CFG80211_CERTIFICATION_ONUS \
 | 
				
			||||||
	MAC80211_RC_MINSTREL \
 | 
						MAC80211_RC_MINSTREL \
 | 
				
			||||||
	MAC80211_RC_MINSTREL_HT \
 | 
						MAC80211_RC_MINSTREL_HT \
 | 
				
			||||||
@@ -1568,7 +1567,7 @@ config-$(call config_package,lib80211) += LIB80211 LIB80211_CRYPT_WEP LIB80211_C
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
config-$(call config_package,airo) += AIRO
 | 
					config-$(call config_package,airo) += AIRO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config-$(call config_package,ath) += ATH_CARDS ATH_COMMON
 | 
					config-$(call config_package,ath) += ATH_CARDS ATH_COMMON ATH_REG_DYNAMIC_USER_REG_HINTS
 | 
				
			||||||
config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH9K_STATION_STATISTICS
 | 
					config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH9K_STATION_STATISTICS
 | 
				
			||||||
config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED
 | 
					config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1742,7 +1741,6 @@ define Build/Prepare
 | 
				
			|||||||
		$(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h
 | 
							$(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version
 | 
						echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version
 | 
				
			||||||
	$(CP) ./files/regdb.txt $(PKG_BUILD_DIR)/net/wireless/db.txt
 | 
					 | 
				
			||||||
endef
 | 
					endef
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),)
 | 
					ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),)
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,11 +1,11 @@
 | 
				
			|||||||
--- a/compat/Makefile
 | 
					--- a/compat/Makefile
 | 
				
			||||||
+++ b/compat/Makefile
 | 
					+++ b/compat/Makefile
 | 
				
			||||||
@@ -39,8 +39,6 @@ compat-$(CPTCFG_KERNEL_4_10) += backport
 | 
					@@ -70,8 +70,6 @@ quiet_cmd_build_OID_registry = GEN     $
 | 
				
			||||||
 
 | 
					 	cmd_build_OID_registry = perl $(src)/build_OID_registry $< $@
 | 
				
			||||||
 compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o
 | 
					 compat-$(CPTCFG_BPAUTO_ASN1_DECODER) += lib-asn1_decoder.o
 | 
				
			||||||
 compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o
 | 
					 compat-$(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION) += lib-oid_registry.o
 | 
				
			||||||
-skcipher-objs += crypto-skcipher.o
 | 
					-skcipher-objs += crypto-skcipher.o
 | 
				
			||||||
-obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o
 | 
					-obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o
 | 
				
			||||||
 compat-$(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP) += drivers-base-devcoredump.o
 | 
					 | 
				
			||||||
 compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o
 | 
					 compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o
 | 
				
			||||||
 cordic-objs += lib-cordic.o
 | 
					 cordic-objs += lib-cordic.o
 | 
				
			||||||
 | 
					 obj-$(CPTCFG_BPAUTO_BUILD_CORDIC) += cordic.o
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								package/kernel/mac80211/patches/006-fix-genl-multicast.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								package/kernel/mac80211/patches/006-fix-genl-multicast.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					--- a/compat/backport-4.12.c
 | 
				
			||||||
 | 
					+++ b/compat/backport-4.12.c
 | 
				
			||||||
 | 
					@@ -225,6 +225,7 @@ int bp_extack_genl_register_family(struc
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* copy this since the family might access it directly */
 | 
				
			||||||
 | 
					 	family->attrbuf = copy->family.attrbuf;
 | 
				
			||||||
 | 
					+	family->mcgrp_offset = copy->family.mcgrp_offset;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	mutex_lock(&copies_mutex);
 | 
				
			||||||
 | 
					 	list_add_tail(©->list, &copies_list);
 | 
				
			||||||
@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					--- a/backport-include/linux/verification.h
 | 
				
			||||||
 | 
					+++ b/backport-include/linux/verification.h
 | 
				
			||||||
 | 
					@@ -1,7 +1,7 @@
 | 
				
			||||||
 | 
					 #ifndef __BP_VERIFICATION_H
 | 
				
			||||||
 | 
					 #define __BP_VERIFICATION_H
 | 
				
			||||||
 | 
					 #include <linux/version.h>
 | 
				
			||||||
 | 
					-#ifndef CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION
 | 
				
			||||||
 | 
					+#if LINUX_VERSION_IS_GEQ(4,7,0) && !defined(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION)
 | 
				
			||||||
 | 
					 #include_next <linux/verification.h>
 | 
				
			||||||
 | 
					 #else
 | 
				
			||||||
 | 
					 #include <linux/key.h>
 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/net/wireless/Kconfig
 | 
					--- a/net/wireless/Kconfig
 | 
				
			||||||
+++ b/net/wireless/Kconfig
 | 
					+++ b/net/wireless/Kconfig
 | 
				
			||||||
@@ -171,7 +171,7 @@ config CFG80211_WEXT_EXPORT
 | 
					@@ -181,7 +181,7 @@ config CFG80211_WEXT_EXPORT
 | 
				
			||||||
 	  wext compatibility symbols to be exported.
 | 
					 	  wext compatibility symbols to be exported.
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 config LIB80211
 | 
					 config LIB80211
 | 
				
			||||||
@@ -9,7 +9,7 @@
 | 
				
			|||||||
 	depends on m
 | 
					 	depends on m
 | 
				
			||||||
 	default n
 | 
					 	default n
 | 
				
			||||||
 	help
 | 
					 	help
 | 
				
			||||||
@@ -181,15 +181,15 @@ config LIB80211
 | 
					@@ -191,15 +191,15 @@ config LIB80211
 | 
				
			||||||
 	  Drivers should select this themselves if needed.
 | 
					 	  Drivers should select this themselves if needed.
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 config LIB80211_CRYPT_WEP
 | 
					 config LIB80211_CRYPT_WEP
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/local-symbols
 | 
					--- a/local-symbols
 | 
				
			||||||
+++ b/local-symbols
 | 
					+++ b/local-symbols
 | 
				
			||||||
@@ -383,45 +383,6 @@ USB_IPHETH=
 | 
					@@ -388,45 +388,6 @@ USB_IPHETH=
 | 
				
			||||||
 USB_SIERRA_NET=
 | 
					 USB_SIERRA_NET=
 | 
				
			||||||
 USB_VL600=
 | 
					 USB_VL600=
 | 
				
			||||||
 USB_NET_CH9200=
 | 
					 USB_NET_CH9200=
 | 
				
			||||||
@@ -121,7 +121,7 @@
 | 
				
			|||||||
 #source "$BACKPORT_DIR/drivers/media/Kconfig"
 | 
					 #source "$BACKPORT_DIR/drivers/media/Kconfig"
 | 
				
			||||||
--- a/Makefile.kernel
 | 
					--- a/Makefile.kernel
 | 
				
			||||||
+++ b/Makefile.kernel
 | 
					+++ b/Makefile.kernel
 | 
				
			||||||
@@ -39,8 +39,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
 | 
					@@ -42,8 +42,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
 | 
				
			||||||
 obj-$(CPTCFG_WLAN) += drivers/net/wireless/
 | 
					 obj-$(CPTCFG_WLAN) += drivers/net/wireless/
 | 
				
			||||||
 #obj-$(CPTCFG_BT) += net/bluetooth/
 | 
					 #obj-$(CPTCFG_BT) += net/bluetooth/
 | 
				
			||||||
 #obj-$(CPTCFG_BT) += drivers/bluetooth/
 | 
					 #obj-$(CPTCFG_BT) += drivers/bluetooth/
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,270 +1,388 @@
 | 
				
			|||||||
--- a/net/mac80211/Kconfig
 | 
					 | 
				
			||||||
+++ b/net/mac80211/Kconfig
 | 
					 | 
				
			||||||
@@ -5,8 +5,6 @@ config MAC80211
 | 
					 | 
				
			||||||
 	depends on CRYPTO
 | 
					 | 
				
			||||||
 	depends on CRYPTO_ARC4
 | 
					 | 
				
			||||||
 	depends on CRYPTO_AES
 | 
					 | 
				
			||||||
-	select BPAUTO_CRYPTO_CCM
 | 
					 | 
				
			||||||
-	depends on CRYPTO_GCM
 | 
					 | 
				
			||||||
 	depends on CRYPTO_CMAC
 | 
					 | 
				
			||||||
 	depends on CRC32
 | 
					 | 
				
			||||||
 	---help---
 | 
					 | 
				
			||||||
--- a/net/mac80211/Makefile
 | 
					--- a/net/mac80211/Makefile
 | 
				
			||||||
+++ b/net/mac80211/Makefile
 | 
					+++ b/net/mac80211/Makefile
 | 
				
			||||||
@@ -16,9 +16,7 @@ mac80211-y := \
 | 
					@@ -6,7 +6,6 @@ mac80211-y := \
 | 
				
			||||||
 | 
					 	driver-ops.o \
 | 
				
			||||||
 | 
					 	sta_info.o \
 | 
				
			||||||
 | 
					 	wep.o \
 | 
				
			||||||
 | 
					-	aead_api.o \
 | 
				
			||||||
 | 
					 	wpa.o \
 | 
				
			||||||
 | 
					 	scan.o offchannel.o \
 | 
				
			||||||
 | 
					 	ht.o agg-tx.o agg-rx.o \
 | 
				
			||||||
 | 
					@@ -16,8 +15,8 @@ mac80211-y := \
 | 
				
			||||||
 | 
					 	rate.o \
 | 
				
			||||||
 	michael.o \
 | 
					 	michael.o \
 | 
				
			||||||
 	tkip.o \
 | 
					 	tkip.o \
 | 
				
			||||||
 	aes_ccm.o \
 | 
					+	aes_ccm.o \
 | 
				
			||||||
-	aes_gcm.o \
 | 
					 | 
				
			||||||
 	aes_cmac.o \
 | 
					 	aes_cmac.o \
 | 
				
			||||||
-	aes_gmac.o \
 | 
					-	aes_gmac.o \
 | 
				
			||||||
 	fils_aead.o \
 | 
					 	fils_aead.o \
 | 
				
			||||||
 	cfg.o \
 | 
					 	cfg.o \
 | 
				
			||||||
 	ethtool.o \
 | 
					 	ethtool.o \
 | 
				
			||||||
--- a/net/mac80211/aes_ccm.c
 | 
					--- a/net/mac80211/aead_api.c
 | 
				
			||||||
+++ b/net/mac80211/aes_ccm.c
 | 
					+++ /dev/null
 | 
				
			||||||
@@ -13,103 +13,132 @@
 | 
					@@ -1,115 +0,0 @@
 | 
				
			||||||
 #include <linux/types.h>
 | 
					-/*
 | 
				
			||||||
 #include <linux/err.h>
 | 
					- * Copyright 2003-2004, Instant802 Networks, Inc.
 | 
				
			||||||
 #include <crypto/aead.h>
 | 
					- * Copyright 2005-2006, Devicescape Software, Inc.
 | 
				
			||||||
+#include <crypto/aes.h>
 | 
					- * Copyright 2014-2015, Qualcomm Atheros, Inc.
 | 
				
			||||||
 
 | 
					- *
 | 
				
			||||||
 #include <net/mac80211.h>
 | 
					- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
 | 
				
			||||||
 #include "key.h"
 | 
					- *
 | 
				
			||||||
 #include "aes_ccm.h"
 | 
					- * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 
 | 
					- * it under the terms of the GNU General Public License version 2 as
 | 
				
			||||||
-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
 | 
					- * published by the Free Software Foundation.
 | 
				
			||||||
-			      u8 *data, size_t data_len, u8 *mic,
 | 
					- */
 | 
				
			||||||
-			      size_t mic_len)
 | 
					-
 | 
				
			||||||
+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
 | 
					-#include <linux/kernel.h>
 | 
				
			||||||
+			    u8 *a, u8 *b)
 | 
					-#include <linux/types.h>
 | 
				
			||||||
 {
 | 
					-#include <linux/err.h>
 | 
				
			||||||
 | 
					-#include <linux/scatterlist.h>
 | 
				
			||||||
 | 
					-#include <crypto/aead.h>
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-#include "aead_api.h"
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
 | 
				
			||||||
 | 
					-		 u8 *data, size_t data_len, u8 *mic)
 | 
				
			||||||
 | 
					-{
 | 
				
			||||||
 | 
					-	size_t mic_len = crypto_aead_authsize(tfm);
 | 
				
			||||||
-	struct scatterlist sg[3];
 | 
					-	struct scatterlist sg[3];
 | 
				
			||||||
-	struct aead_request *aead_req;
 | 
					-	struct aead_request *aead_req;
 | 
				
			||||||
-	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
 | 
					-	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
 | 
				
			||||||
-	u8 *__aad;
 | 
					-	u8 *__aad;
 | 
				
			||||||
+	int i;
 | 
					-
 | 
				
			||||||
 
 | 
					-	aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
 | 
				
			||||||
-	aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
 | 
					 | 
				
			||||||
-	if (!aead_req)
 | 
					-	if (!aead_req)
 | 
				
			||||||
-		return -ENOMEM;
 | 
					-		return -ENOMEM;
 | 
				
			||||||
+	crypto_cipher_encrypt_one(tfm, b, b_0);
 | 
					-
 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	__aad = (u8 *)aead_req + reqsize;
 | 
					-	__aad = (u8 *)aead_req + reqsize;
 | 
				
			||||||
-	memcpy(__aad, aad, CCM_AAD_LEN);
 | 
					-	memcpy(__aad, aad, aad_len);
 | 
				
			||||||
+	/* Extra Authenticate-only data (always two AES blocks) */
 | 
					-
 | 
				
			||||||
+	for (i = 0; i < AES_BLOCK_SIZE; i++)
 | 
					 | 
				
			||||||
+		aad[i] ^= b[i];
 | 
					 | 
				
			||||||
+	crypto_cipher_encrypt_one(tfm, b, aad);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	sg_init_table(sg, 3);
 | 
					-	sg_init_table(sg, 3);
 | 
				
			||||||
-	sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
 | 
					-	sg_set_buf(&sg[0], __aad, aad_len);
 | 
				
			||||||
-	sg_set_buf(&sg[1], data, data_len);
 | 
					-	sg_set_buf(&sg[1], data, data_len);
 | 
				
			||||||
-	sg_set_buf(&sg[2], mic, mic_len);
 | 
					-	sg_set_buf(&sg[2], mic, mic_len);
 | 
				
			||||||
+	aad += AES_BLOCK_SIZE;
 | 
					-
 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	aead_request_set_tfm(aead_req, tfm);
 | 
					-	aead_request_set_tfm(aead_req, tfm);
 | 
				
			||||||
-	aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
 | 
					-	aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
 | 
				
			||||||
-	aead_request_set_ad(aead_req, sg[0].length);
 | 
					-	aead_request_set_ad(aead_req, sg[0].length);
 | 
				
			||||||
+	for (i = 0; i < AES_BLOCK_SIZE; i++)
 | 
					-
 | 
				
			||||||
+		aad[i] ^= b[i];
 | 
					 | 
				
			||||||
+	crypto_cipher_encrypt_one(tfm, a, aad);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	crypto_aead_encrypt(aead_req);
 | 
					-	crypto_aead_encrypt(aead_req);
 | 
				
			||||||
-	kzfree(aead_req);
 | 
					-	kzfree(aead_req);
 | 
				
			||||||
+	/* Mask out bits from auth-only-b_0 */
 | 
					-
 | 
				
			||||||
+	b_0[0] &= 0x07;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	return 0;
 | 
					-	return 0;
 | 
				
			||||||
+	/* S_0 is used to encrypt T (= MIC) */
 | 
					-}
 | 
				
			||||||
+	b_0[14] = 0;
 | 
					-
 | 
				
			||||||
+	b_0[15] = 0;
 | 
					-int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
 | 
				
			||||||
+	crypto_cipher_encrypt_one(tfm, s_0, b_0);
 | 
					-		 u8 *data, size_t data_len, u8 *mic)
 | 
				
			||||||
 }
 | 
					-{
 | 
				
			||||||
 
 | 
					-	size_t mic_len = crypto_aead_authsize(tfm);
 | 
				
			||||||
-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
 | 
					 | 
				
			||||||
-			      u8 *data, size_t data_len, u8 *mic,
 | 
					 | 
				
			||||||
-			      size_t mic_len)
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 | 
					 | 
				
			||||||
+			       u8 *data, size_t data_len, u8 *mic,
 | 
					 | 
				
			||||||
+			       size_t mic_len)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
-	struct scatterlist sg[3];
 | 
					-	struct scatterlist sg[3];
 | 
				
			||||||
-	struct aead_request *aead_req;
 | 
					-	struct aead_request *aead_req;
 | 
				
			||||||
-	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
 | 
					-	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
 | 
				
			||||||
-	u8 *__aad;
 | 
					-	u8 *__aad;
 | 
				
			||||||
-	int err;
 | 
					-	int err;
 | 
				
			||||||
+	int i, j, last_len, num_blocks;
 | 
					-
 | 
				
			||||||
+	u8 b[AES_BLOCK_SIZE];
 | 
					 | 
				
			||||||
+	u8 s_0[AES_BLOCK_SIZE];
 | 
					 | 
				
			||||||
+	u8 e[AES_BLOCK_SIZE];
 | 
					 | 
				
			||||||
+	u8 *pos, *cpos;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	if (data_len == 0)
 | 
					-	if (data_len == 0)
 | 
				
			||||||
-		return -EINVAL;
 | 
					-		return -EINVAL;
 | 
				
			||||||
+	num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
 | 
					-
 | 
				
			||||||
+	last_len = data_len % AES_BLOCK_SIZE;
 | 
					-	aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
 | 
				
			||||||
+	aes_ccm_prepare(tfm, b_0, aad, s_0, b, b);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
 | 
					 | 
				
			||||||
-	if (!aead_req)
 | 
					-	if (!aead_req)
 | 
				
			||||||
-		return -ENOMEM;
 | 
					-		return -ENOMEM;
 | 
				
			||||||
+	/* Process payload blocks */
 | 
					-
 | 
				
			||||||
+	pos = data;
 | 
					 | 
				
			||||||
+	cpos = data;
 | 
					 | 
				
			||||||
+	for (j = 1; j <= num_blocks; j++) {
 | 
					 | 
				
			||||||
+		int blen = (j == num_blocks && last_len) ?
 | 
					 | 
				
			||||||
+			last_len : AES_BLOCK_SIZE;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	__aad = (u8 *)aead_req + reqsize;
 | 
					-	__aad = (u8 *)aead_req + reqsize;
 | 
				
			||||||
-	memcpy(__aad, aad, CCM_AAD_LEN);
 | 
					-	memcpy(__aad, aad, aad_len);
 | 
				
			||||||
+		/* Authentication followed by encryption */
 | 
					-
 | 
				
			||||||
+		for (i = 0; i < blen; i++)
 | 
					 | 
				
			||||||
+			b[i] ^= pos[i];
 | 
					 | 
				
			||||||
+		crypto_cipher_encrypt_one(tfm, b, b);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	sg_init_table(sg, 3);
 | 
					-	sg_init_table(sg, 3);
 | 
				
			||||||
-	sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
 | 
					-	sg_set_buf(&sg[0], __aad, aad_len);
 | 
				
			||||||
-	sg_set_buf(&sg[1], data, data_len);
 | 
					-	sg_set_buf(&sg[1], data, data_len);
 | 
				
			||||||
-	sg_set_buf(&sg[2], mic, mic_len);
 | 
					-	sg_set_buf(&sg[2], mic, mic_len);
 | 
				
			||||||
+		b_0[14] = (j >> 8) & 0xff;
 | 
					-
 | 
				
			||||||
+		b_0[15] = j & 0xff;
 | 
					 | 
				
			||||||
+		crypto_cipher_encrypt_one(tfm, e, b_0);
 | 
					 | 
				
			||||||
+		for (i = 0; i < blen; i++)
 | 
					 | 
				
			||||||
+			*cpos++ = *pos++ ^ e[i];
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	aead_request_set_tfm(aead_req, tfm);
 | 
					-	aead_request_set_tfm(aead_req, tfm);
 | 
				
			||||||
-	aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
 | 
					-	aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
 | 
				
			||||||
-	aead_request_set_ad(aead_req, sg[0].length);
 | 
					-	aead_request_set_ad(aead_req, sg[0].length);
 | 
				
			||||||
+	for (i = 0; i < mic_len; i++)
 | 
					-
 | 
				
			||||||
+		mic[i] = b[i] ^ s_0[i];
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	err = crypto_aead_decrypt(aead_req);
 | 
					-	err = crypto_aead_decrypt(aead_req);
 | 
				
			||||||
-	kzfree(aead_req);
 | 
					-	kzfree(aead_req);
 | 
				
			||||||
+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 | 
					-
 | 
				
			||||||
+			      u8 *data, size_t data_len, u8 *mic,
 | 
					 | 
				
			||||||
+			      size_t mic_len)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	int i, j, last_len, num_blocks;
 | 
					 | 
				
			||||||
+	u8 *pos, *cpos;
 | 
					 | 
				
			||||||
+	u8 a[AES_BLOCK_SIZE];
 | 
					 | 
				
			||||||
+	u8 b[AES_BLOCK_SIZE];
 | 
					 | 
				
			||||||
+	u8 s_0[AES_BLOCK_SIZE];
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	return err;
 | 
					-	return err;
 | 
				
			||||||
+	num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
 | 
					-}
 | 
				
			||||||
+	last_len = data_len % AES_BLOCK_SIZE;
 | 
					-
 | 
				
			||||||
+	aes_ccm_prepare(tfm, b_0, aad, s_0, a, b);
 | 
					-struct crypto_aead *
 | 
				
			||||||
+
 | 
					-aead_key_setup_encrypt(const char *alg, const u8 key[],
 | 
				
			||||||
+	/* Process payload blocks */
 | 
					-		       size_t key_len, size_t mic_len)
 | 
				
			||||||
+	cpos = data;
 | 
					-{
 | 
				
			||||||
+	pos = data;
 | 
					 | 
				
			||||||
+	for (j = 1; j <= num_blocks; j++) {
 | 
					 | 
				
			||||||
+		int blen = (j == num_blocks && last_len) ?
 | 
					 | 
				
			||||||
+			last_len : AES_BLOCK_SIZE;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		/* Decryption followed by authentication */
 | 
					 | 
				
			||||||
+		b_0[14] = (j >> 8) & 0xff;
 | 
					 | 
				
			||||||
+		b_0[15] = j & 0xff;
 | 
					 | 
				
			||||||
+		crypto_cipher_encrypt_one(tfm, b, b_0);
 | 
					 | 
				
			||||||
+		for (i = 0; i < blen; i++) {
 | 
					 | 
				
			||||||
+			*pos = *cpos++ ^ b[i];
 | 
					 | 
				
			||||||
+			a[i] ^= *pos++;
 | 
					 | 
				
			||||||
+		}
 | 
					 | 
				
			||||||
+		crypto_cipher_encrypt_one(tfm, a, a);
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	for (i = 0; i < mic_len; i++) {
 | 
					 | 
				
			||||||
+		if ((mic[i] ^ s_0[i]) != a[i])
 | 
					 | 
				
			||||||
+			return -1;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
 | 
					 | 
				
			||||||
-						    size_t key_len,
 | 
					 | 
				
			||||||
-						    size_t mic_len)
 | 
					 | 
				
			||||||
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
 | 
					 | 
				
			||||||
+						      size_t key_len,
 | 
					 | 
				
			||||||
+						      size_t mic_len)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
-	struct crypto_aead *tfm;
 | 
					-	struct crypto_aead *tfm;
 | 
				
			||||||
-	int err;
 | 
					-	int err;
 | 
				
			||||||
-
 | 
					-
 | 
				
			||||||
-	tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
 | 
					-	tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
 | 
				
			||||||
-	if (IS_ERR(tfm))
 | 
					-	if (IS_ERR(tfm))
 | 
				
			||||||
-		return tfm;
 | 
					-		return tfm;
 | 
				
			||||||
+	struct crypto_cipher *tfm;
 | 
					-
 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	err = crypto_aead_setkey(tfm, key, key_len);
 | 
					-	err = crypto_aead_setkey(tfm, key, key_len);
 | 
				
			||||||
-	if (err)
 | 
					-	if (err)
 | 
				
			||||||
-		goto free_aead;
 | 
					-		goto free_aead;
 | 
				
			||||||
-	err = crypto_aead_setauthsize(tfm, mic_len);
 | 
					-	err = crypto_aead_setauthsize(tfm, mic_len);
 | 
				
			||||||
-	if (err)
 | 
					-	if (err)
 | 
				
			||||||
-		goto free_aead;
 | 
					-		goto free_aead;
 | 
				
			||||||
+	tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
 | 
					-
 | 
				
			||||||
+	if (!IS_ERR(tfm))
 | 
					-	return tfm;
 | 
				
			||||||
+		crypto_cipher_setkey(tfm, key, key_len);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	return tfm;
 | 
					 | 
				
			||||||
-
 | 
					-
 | 
				
			||||||
-free_aead:
 | 
					-free_aead:
 | 
				
			||||||
-	crypto_free_aead(tfm);
 | 
					-	crypto_free_aead(tfm);
 | 
				
			||||||
-	return ERR_PTR(err);
 | 
					-	return ERR_PTR(err);
 | 
				
			||||||
 }
 | 
					-}
 | 
				
			||||||
 
 | 
					-
 | 
				
			||||||
-void ieee80211_aes_key_free(struct crypto_aead *tfm)
 | 
					-void aead_key_free(struct crypto_aead *tfm)
 | 
				
			||||||
+
 | 
					-{
 | 
				
			||||||
+void ieee80211_aes_key_free(struct crypto_cipher *tfm)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
-	crypto_free_aead(tfm);
 | 
					-	crypto_free_aead(tfm);
 | 
				
			||||||
+	crypto_free_cipher(tfm);
 | 
					-}
 | 
				
			||||||
 }
 | 
					--- a/net/mac80211/aead_api.h
 | 
				
			||||||
--- a/net/mac80211/aes_gmac.h
 | 
					+++ /dev/null
 | 
				
			||||||
+++ b/net/mac80211/aes_gmac.h
 | 
					@@ -1,27 +0,0 @@
 | 
				
			||||||
@@ -15,10 +15,22 @@
 | 
					-/*
 | 
				
			||||||
 #define GMAC_MIC_LEN	16
 | 
					- * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 #define GMAC_NONCE_LEN	12
 | 
					- * it under the terms of the GNU General Public License version 2 as
 | 
				
			||||||
 | 
					- * published by the Free Software Foundation.
 | 
				
			||||||
 | 
					- */
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-#ifndef _AEAD_API_H
 | 
				
			||||||
 | 
					-#define _AEAD_API_H
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-#include <crypto/aead.h>
 | 
				
			||||||
 | 
					-#include <linux/crypto.h>
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-struct crypto_aead *
 | 
				
			||||||
 | 
					-aead_key_setup_encrypt(const char *alg, const u8 key[],
 | 
				
			||||||
 | 
					-		       size_t key_len, size_t mic_len);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
 | 
				
			||||||
 | 
					-		 size_t aad_len, u8 *data,
 | 
				
			||||||
 | 
					-		 size_t data_len, u8 *mic);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
 | 
				
			||||||
 | 
					-		 size_t aad_len, u8 *data,
 | 
				
			||||||
 | 
					-		 size_t data_len, u8 *mic);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-void aead_key_free(struct crypto_aead *tfm);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-#endif /* _AEAD_API_H */
 | 
				
			||||||
 | 
					--- a/net/mac80211/aes_ccm.h
 | 
				
			||||||
 | 
					+++ b/net/mac80211/aes_ccm.h
 | 
				
			||||||
 | 
					@@ -10,39 +10,17 @@
 | 
				
			||||||
 | 
					 #ifndef AES_CCM_H
 | 
				
			||||||
 | 
					 #define AES_CCM_H
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
 | 
					-#include "aead_api.h"
 | 
				
			||||||
-						 size_t key_len);
 | 
					-
 | 
				
			||||||
-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
 | 
					-#define CCM_AAD_LEN	32
 | 
				
			||||||
-		       const u8 *data, size_t data_len, u8 *mic);
 | 
					-
 | 
				
			||||||
-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
 | 
					-static inline struct crypto_aead *
 | 
				
			||||||
+static inline struct crypto_aead *
 | 
					-ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len)
 | 
				
			||||||
+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
 | 
					-{
 | 
				
			||||||
 | 
					-	return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len);
 | 
				
			||||||
 | 
					-}
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-static inline int
 | 
				
			||||||
 | 
					-ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm,
 | 
				
			||||||
 | 
					-			  u8 *b_0, u8 *aad, u8 *data,
 | 
				
			||||||
 | 
					-			  size_t data_len, u8 *mic)
 | 
				
			||||||
 | 
					-{
 | 
				
			||||||
 | 
					-	return aead_encrypt(tfm, b_0, aad + 2,
 | 
				
			||||||
 | 
					-			    be16_to_cpup((__be16 *)aad),
 | 
				
			||||||
 | 
					-			    data, data_len, mic);
 | 
				
			||||||
 | 
					-}
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-static inline int
 | 
				
			||||||
 | 
					-ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm,
 | 
				
			||||||
 | 
					-			  u8 *b_0, u8 *aad, u8 *data,
 | 
				
			||||||
 | 
					-			  size_t data_len, u8 *mic)
 | 
				
			||||||
 | 
					-{
 | 
				
			||||||
 | 
					-	return aead_decrypt(tfm, b_0, aad + 2,
 | 
				
			||||||
 | 
					-			    be16_to_cpup((__be16 *)aad),
 | 
				
			||||||
 | 
					-			    data, data_len, mic);
 | 
				
			||||||
 | 
					-}
 | 
				
			||||||
 | 
					+#include <linux/crypto.h>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-static inline void ieee80211_aes_key_free(struct crypto_aead *tfm)
 | 
				
			||||||
 | 
					-{
 | 
				
			||||||
 | 
					-	return aead_key_free(tfm);
 | 
				
			||||||
 | 
					-}
 | 
				
			||||||
 | 
					+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
 | 
				
			||||||
 | 
					+						      size_t key_len,
 | 
				
			||||||
 | 
					+						      size_t mic_len);
 | 
				
			||||||
 | 
					+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 | 
				
			||||||
 | 
					+			       u8 *data, size_t data_len, u8 *mic,
 | 
				
			||||||
 | 
					+			       size_t mic_len);
 | 
				
			||||||
 | 
					+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 | 
				
			||||||
 | 
					+			      u8 *data, size_t data_len, u8 *mic,
 | 
				
			||||||
 | 
					+			      size_t mic_len);
 | 
				
			||||||
 | 
					+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 #endif /* AES_CCM_H */
 | 
				
			||||||
 | 
					--- /dev/null
 | 
				
			||||||
 | 
					+++ b/net/mac80211/aes_gcm.c
 | 
				
			||||||
 | 
					@@ -0,0 +1,109 @@
 | 
				
			||||||
 | 
					+/*
 | 
				
			||||||
 | 
					+ * Copyright 2014-2015, Qualcomm Atheros, Inc.
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					+ * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					+ * it under the terms of the GNU General Public License version 2 as
 | 
				
			||||||
 | 
					+ * published by the Free Software Foundation.
 | 
				
			||||||
 | 
					+ */
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <linux/kernel.h>
 | 
				
			||||||
 | 
					+#include <linux/types.h>
 | 
				
			||||||
 | 
					+#include <linux/err.h>
 | 
				
			||||||
 | 
					+#include <crypto/aead.h>
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+#include <net/mac80211.h>
 | 
				
			||||||
 | 
					+#include "key.h"
 | 
				
			||||||
 | 
					+#include "aes_gcm.h"
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
 | 
				
			||||||
 | 
					+			      u8 *data, size_t data_len, u8 *mic)
 | 
				
			||||||
+{
 | 
					+{
 | 
				
			||||||
+	return NULL;
 | 
					+	struct scatterlist sg[3];
 | 
				
			||||||
 | 
					+	struct aead_request *aead_req;
 | 
				
			||||||
 | 
					+	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
 | 
				
			||||||
 | 
					+	u8 *__aad;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
 | 
				
			||||||
 | 
					+	if (!aead_req)
 | 
				
			||||||
 | 
					+		return -ENOMEM;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	__aad = (u8 *)aead_req + reqsize;
 | 
				
			||||||
 | 
					+	memcpy(__aad, aad, GCM_AAD_LEN);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	sg_init_table(sg, 3);
 | 
				
			||||||
 | 
					+	sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
 | 
				
			||||||
 | 
					+	sg_set_buf(&sg[1], data, data_len);
 | 
				
			||||||
 | 
					+	sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	aead_request_set_tfm(aead_req, tfm);
 | 
				
			||||||
 | 
					+	aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
 | 
				
			||||||
 | 
					+	aead_request_set_ad(aead_req, sg[0].length);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	crypto_aead_encrypt(aead_req);
 | 
				
			||||||
 | 
					+	kzfree(aead_req);
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
+}
 | 
					+}
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
+static inline int
 | 
					+int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
 | 
				
			||||||
+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
 | 
					+			      u8 *data, size_t data_len, u8 *mic)
 | 
				
			||||||
+		   const u8 *data, size_t data_len, u8 *mic)
 | 
					 | 
				
			||||||
+{
 | 
					+{
 | 
				
			||||||
+	return -EOPNOTSUPP;
 | 
					+	struct scatterlist sg[3];
 | 
				
			||||||
 | 
					+	struct aead_request *aead_req;
 | 
				
			||||||
 | 
					+	int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
 | 
				
			||||||
 | 
					+	u8 *__aad;
 | 
				
			||||||
 | 
					+	int err;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	if (data_len == 0)
 | 
				
			||||||
 | 
					+		return -EINVAL;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
 | 
				
			||||||
 | 
					+	if (!aead_req)
 | 
				
			||||||
 | 
					+		return -ENOMEM;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	__aad = (u8 *)aead_req + reqsize;
 | 
				
			||||||
 | 
					+	memcpy(__aad, aad, GCM_AAD_LEN);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	sg_init_table(sg, 3);
 | 
				
			||||||
 | 
					+	sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
 | 
				
			||||||
 | 
					+	sg_set_buf(&sg[1], data, data_len);
 | 
				
			||||||
 | 
					+	sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	aead_request_set_tfm(aead_req, tfm);
 | 
				
			||||||
 | 
					+	aead_request_set_crypt(aead_req, sg, sg,
 | 
				
			||||||
 | 
					+			       data_len + IEEE80211_GCMP_MIC_LEN, j_0);
 | 
				
			||||||
 | 
					+	aead_request_set_ad(aead_req, sg[0].length);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	err = crypto_aead_decrypt(aead_req);
 | 
				
			||||||
 | 
					+	kzfree(aead_req);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return err;
 | 
				
			||||||
+}
 | 
					+}
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
 | 
					+struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
 | 
				
			||||||
 | 
					+							size_t key_len)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct crypto_aead *tfm;
 | 
				
			||||||
 | 
					+	int err;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
 | 
				
			||||||
 | 
					+	if (IS_ERR(tfm))
 | 
				
			||||||
 | 
					+		return tfm;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	err = crypto_aead_setkey(tfm, key, key_len);
 | 
				
			||||||
 | 
					+	if (err)
 | 
				
			||||||
 | 
					+		goto free_aead;
 | 
				
			||||||
 | 
					+	err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
 | 
				
			||||||
 | 
					+	if (err)
 | 
				
			||||||
 | 
					+		goto free_aead;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return tfm;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+free_aead:
 | 
				
			||||||
 | 
					+	crypto_free_aead(tfm);
 | 
				
			||||||
 | 
					+	return ERR_PTR(err);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	crypto_free_aead(tfm);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					--- a/net/mac80211/aes_gcm.h
 | 
				
			||||||
 | 
					+++ b/net/mac80211/aes_gcm.h
 | 
				
			||||||
 | 
					@@ -9,38 +9,30 @@
 | 
				
			||||||
 | 
					 #ifndef AES_GCM_H
 | 
				
			||||||
 | 
					 #define AES_GCM_H
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-#include "aead_api.h"
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-#define GCM_AAD_LEN	32
 | 
				
			||||||
 | 
					+#include <linux/crypto.h>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm,
 | 
				
			||||||
 | 
					-					    u8 *j_0, u8 *aad,  u8 *data,
 | 
				
			||||||
 | 
					-					    size_t data_len, u8 *mic)
 | 
				
			||||||
+static inline void
 | 
					+static inline void
 | 
				
			||||||
+ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
 | 
					+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
 | 
				
			||||||
+{
 | 
					+			  u8 *data, size_t data_len, u8 *mic)
 | 
				
			||||||
+}
 | 
					 {
 | 
				
			||||||
 | 
					-	return aead_encrypt(tfm, j_0, aad + 2,
 | 
				
			||||||
 | 
					-			    be16_to_cpup((__be16 *)aad),
 | 
				
			||||||
 | 
					-			    data, data_len, mic);
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 #endif /* AES_GMAC_H */
 | 
					-static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm,
 | 
				
			||||||
--- a/net/mac80211/key.h
 | 
					-					    u8 *j_0, u8 *aad, u8 *data,
 | 
				
			||||||
+++ b/net/mac80211/key.h
 | 
					-					    size_t data_len, u8 *mic)
 | 
				
			||||||
@@ -88,7 +88,7 @@ struct ieee80211_key {
 | 
					+static inline int
 | 
				
			||||||
 			 * Management frames.
 | 
					+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
 | 
				
			||||||
 			 */
 | 
					+			  u8 *data, size_t data_len, u8 *mic)
 | 
				
			||||||
 			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
 | 
					 {
 | 
				
			||||||
-			struct crypto_aead *tfm;
 | 
					-	return aead_decrypt(tfm, j_0, aad + 2,
 | 
				
			||||||
+			struct crypto_cipher *tfm;
 | 
					-			    be16_to_cpup((__be16 *)aad),
 | 
				
			||||||
 			u32 replays; /* dot11RSNAStatsCCMPReplays */
 | 
					-			    data, data_len, mic);
 | 
				
			||||||
 		} ccmp;
 | 
					+    return -EOPNOTSUPP;
 | 
				
			||||||
 		struct {
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static inline struct crypto_aead *
 | 
				
			||||||
 | 
					 ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	return aead_key_setup_encrypt("gcm(aes)", key,
 | 
				
			||||||
 | 
					-				      key_len, IEEE80211_GCMP_MIC_LEN);
 | 
				
			||||||
 | 
					+    return NULL;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
 | 
				
			||||||
 | 
					+static inline void
 | 
				
			||||||
 | 
					+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	return aead_key_free(tfm);
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 #endif /* AES_GCM_H */
 | 
				
			||||||
--- a/net/mac80211/wpa.c
 | 
					--- a/net/mac80211/wpa.c
 | 
				
			||||||
+++ b/net/mac80211/wpa.c
 | 
					+++ b/net/mac80211/wpa.c
 | 
				
			||||||
@@ -306,7 +306,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
 | 
					@@ -306,7 +306,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
 | 
				
			||||||
@@ -318,7 +436,7 @@
 | 
				
			|||||||
 	pos += IEEE80211_CCMP_HDR_LEN;
 | 
					 	pos += IEEE80211_CCMP_HDR_LEN;
 | 
				
			||||||
-	ccmp_special_blocks(skb, pn, b_0, aad);
 | 
					-	ccmp_special_blocks(skb, pn, b_0, aad);
 | 
				
			||||||
-	return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
 | 
					-	return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
 | 
				
			||||||
-					 skb_put(skb, mic_len), mic_len);
 | 
					-					 skb_put(skb, mic_len));
 | 
				
			||||||
+	ccmp_special_blocks(skb, pn, b_0, aad, len);
 | 
					+	ccmp_special_blocks(skb, pn, b_0, aad, len);
 | 
				
			||||||
+	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
 | 
					+	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
 | 
				
			||||||
+				  skb_put(skb, mic_len), mic_len);
 | 
					+				  skb_put(skb, mic_len), mic_len);
 | 
				
			||||||
@@ -327,7 +445,7 @@
 | 
				
			|||||||
 }
 | 
					 }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -537,7 +536,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 | 
					@@ -537,13 +536,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 | 
				
			||||||
 			u8 aad[2 * AES_BLOCK_SIZE];
 | 
					 			u8 aad[2 * AES_BLOCK_SIZE];
 | 
				
			||||||
 			u8 b_0[AES_BLOCK_SIZE];
 | 
					 			u8 b_0[AES_BLOCK_SIZE];
 | 
				
			||||||
 			/* hardware didn't decrypt/verify MIC */
 | 
					 			/* hardware didn't decrypt/verify MIC */
 | 
				
			||||||
@@ -336,6 +454,13 @@
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 			if (ieee80211_aes_ccm_decrypt(
 | 
					 			if (ieee80211_aes_ccm_decrypt(
 | 
				
			||||||
 				    key->u.ccmp.tfm, b_0, aad,
 | 
					 				    key->u.ccmp.tfm, b_0, aad,
 | 
				
			||||||
 | 
					 				    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
 | 
				
			||||||
 | 
					 				    data_len,
 | 
				
			||||||
 | 
					-				    skb->data + skb->len - mic_len))
 | 
				
			||||||
 | 
					+				    skb->data + skb->len - mic_len, mic_len))
 | 
				
			||||||
 | 
					 				return RX_DROP_UNUSABLE;
 | 
				
			||||||
 | 
					 		}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
@@ -639,7 +638,7 @@ static int gcmp_encrypt_skb(struct ieee8
 | 
					@@ -639,7 +638,7 @@ static int gcmp_encrypt_skb(struct ieee8
 | 
				
			||||||
 	u8 *pos;
 | 
					 	u8 *pos;
 | 
				
			||||||
 	u8 pn[6];
 | 
					 	u8 pn[6];
 | 
				
			||||||
@@ -379,70 +504,202 @@
 | 
				
			|||||||
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 | 
					 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	if (!ieee80211_is_mgmt(hdr->frame_control))
 | 
					 	if (!ieee80211_is_mgmt(hdr->frame_control))
 | 
				
			||||||
--- a/net/mac80211/aes_ccm.h
 | 
					--- /dev/null
 | 
				
			||||||
+++ b/net/mac80211/aes_ccm.h
 | 
					+++ b/net/mac80211/aes_ccm.c
 | 
				
			||||||
@@ -12,17 +12,15 @@
 | 
					@@ -0,0 +1,144 @@
 | 
				
			||||||
 
 | 
					+/*
 | 
				
			||||||
 #include <linux/crypto.h>
 | 
					+ * Copyright 2003-2004, Instant802 Networks, Inc.
 | 
				
			||||||
 
 | 
					+ * Copyright 2005-2006, Devicescape Software, Inc.
 | 
				
			||||||
-#define CCM_AAD_LEN	32
 | 
					+ *
 | 
				
			||||||
-
 | 
					+ * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
 | 
				
			||||||
-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
 | 
					+ *
 | 
				
			||||||
-						    size_t key_len,
 | 
					+ * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
-						    size_t mic_len);
 | 
					+ * it under the terms of the GNU General Public License version 2 as
 | 
				
			||||||
-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
 | 
					+ * published by the Free Software Foundation.
 | 
				
			||||||
-			      u8 *data, size_t data_len, u8 *mic,
 | 
					+ */
 | 
				
			||||||
-			      size_t mic_len);
 | 
					+
 | 
				
			||||||
-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
 | 
					+#include <linux/kernel.h>
 | 
				
			||||||
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
 | 
					+#include <linux/types.h>
 | 
				
			||||||
+						      size_t key_len,
 | 
					+#include <linux/err.h>
 | 
				
			||||||
+						      size_t mic_len);
 | 
					+#include <crypto/aead.h>
 | 
				
			||||||
+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 | 
					+#include <crypto/aes.h>
 | 
				
			||||||
+			       u8 *data, size_t data_len, u8 *mic,
 | 
					+
 | 
				
			||||||
+			       size_t mic_len);
 | 
					+#include <net/mac80211.h>
 | 
				
			||||||
+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 | 
					+#include "key.h"
 | 
				
			||||||
 			      u8 *data, size_t data_len, u8 *mic,
 | 
					+#include "aes_ccm.h"
 | 
				
			||||||
 			      size_t mic_len);
 | 
					+
 | 
				
			||||||
-void ieee80211_aes_key_free(struct crypto_aead *tfm);
 | 
					+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
 | 
				
			||||||
+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
 | 
					+			    u8 *a, u8 *b)
 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 #endif /* AES_CCM_H */
 | 
					 | 
				
			||||||
--- a/net/mac80211/aes_gcm.h
 | 
					 | 
				
			||||||
+++ b/net/mac80211/aes_gcm.h
 | 
					 | 
				
			||||||
@@ -11,14 +11,28 @@
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 #include <linux/crypto.h>
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-#define GCM_AAD_LEN	32
 | 
					 | 
				
			||||||
+static inline void
 | 
					 | 
				
			||||||
+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
 | 
					 | 
				
			||||||
+			  u8 *data, size_t data_len, u8 *mic)
 | 
					 | 
				
			||||||
+{
 | 
					+{
 | 
				
			||||||
+}
 | 
					+	int i;
 | 
				
			||||||
 
 | 
					+
 | 
				
			||||||
-int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
 | 
					+	crypto_cipher_encrypt_one(tfm, b, b_0);
 | 
				
			||||||
-			      u8 *data, size_t data_len, u8 *mic);
 | 
					+
 | 
				
			||||||
-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
 | 
					+	/* Extra Authenticate-only data (always two AES blocks) */
 | 
				
			||||||
-			      u8 *data, size_t data_len, u8 *mic);
 | 
					+	for (i = 0; i < AES_BLOCK_SIZE; i++)
 | 
				
			||||||
-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
 | 
					+		aad[i] ^= b[i];
 | 
				
			||||||
-							size_t key_len);
 | 
					+	crypto_cipher_encrypt_one(tfm, b, aad);
 | 
				
			||||||
-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
 | 
					+
 | 
				
			||||||
+static inline int
 | 
					+	aad += AES_BLOCK_SIZE;
 | 
				
			||||||
+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
 | 
					+
 | 
				
			||||||
+			  u8 *data, size_t data_len, u8 *mic)
 | 
					+	for (i = 0; i < AES_BLOCK_SIZE; i++)
 | 
				
			||||||
+{
 | 
					+		aad[i] ^= b[i];
 | 
				
			||||||
+    return -EOPNOTSUPP;
 | 
					+	crypto_cipher_encrypt_one(tfm, a, aad);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Mask out bits from auth-only-b_0 */
 | 
				
			||||||
 | 
					+	b_0[0] &= 0x07;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* S_0 is used to encrypt T (= MIC) */
 | 
				
			||||||
 | 
					+	b_0[14] = 0;
 | 
				
			||||||
 | 
					+	b_0[15] = 0;
 | 
				
			||||||
 | 
					+	crypto_cipher_encrypt_one(tfm, s_0, b_0);
 | 
				
			||||||
+}
 | 
					+}
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 | 
				
			||||||
 | 
					+			       u8 *data, size_t data_len, u8 *mic,
 | 
				
			||||||
 | 
					+			       size_t mic_len)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	int i, j, last_len, num_blocks;
 | 
				
			||||||
 | 
					+	u8 b[AES_BLOCK_SIZE];
 | 
				
			||||||
 | 
					+	u8 s_0[AES_BLOCK_SIZE];
 | 
				
			||||||
 | 
					+	u8 e[AES_BLOCK_SIZE];
 | 
				
			||||||
 | 
					+	u8 *pos, *cpos;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
 | 
				
			||||||
 | 
					+	last_len = data_len % AES_BLOCK_SIZE;
 | 
				
			||||||
 | 
					+	aes_ccm_prepare(tfm, b_0, aad, s_0, b, b);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Process payload blocks */
 | 
				
			||||||
 | 
					+	pos = data;
 | 
				
			||||||
 | 
					+	cpos = data;
 | 
				
			||||||
 | 
					+	for (j = 1; j <= num_blocks; j++) {
 | 
				
			||||||
 | 
					+		int blen = (j == num_blocks && last_len) ?
 | 
				
			||||||
 | 
					+			last_len : AES_BLOCK_SIZE;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		/* Authentication followed by encryption */
 | 
				
			||||||
 | 
					+		for (i = 0; i < blen; i++)
 | 
				
			||||||
 | 
					+			b[i] ^= pos[i];
 | 
				
			||||||
 | 
					+		crypto_cipher_encrypt_one(tfm, b, b);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		b_0[14] = (j >> 8) & 0xff;
 | 
				
			||||||
 | 
					+		b_0[15] = j & 0xff;
 | 
				
			||||||
 | 
					+		crypto_cipher_encrypt_one(tfm, e, b_0);
 | 
				
			||||||
 | 
					+		for (i = 0; i < blen; i++)
 | 
				
			||||||
 | 
					+			*cpos++ = *pos++ ^ e[i];
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	for (i = 0; i < mic_len; i++)
 | 
				
			||||||
 | 
					+		mic[i] = b[i] ^ s_0[i];
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 | 
				
			||||||
 | 
					+			      u8 *data, size_t data_len, u8 *mic,
 | 
				
			||||||
 | 
					+			      size_t mic_len)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	int i, j, last_len, num_blocks;
 | 
				
			||||||
 | 
					+	u8 *pos, *cpos;
 | 
				
			||||||
 | 
					+	u8 a[AES_BLOCK_SIZE];
 | 
				
			||||||
 | 
					+	u8 b[AES_BLOCK_SIZE];
 | 
				
			||||||
 | 
					+	u8 s_0[AES_BLOCK_SIZE];
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
 | 
				
			||||||
 | 
					+	last_len = data_len % AES_BLOCK_SIZE;
 | 
				
			||||||
 | 
					+	aes_ccm_prepare(tfm, b_0, aad, s_0, a, b);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	/* Process payload blocks */
 | 
				
			||||||
 | 
					+	cpos = data;
 | 
				
			||||||
 | 
					+	pos = data;
 | 
				
			||||||
 | 
					+	for (j = 1; j <= num_blocks; j++) {
 | 
				
			||||||
 | 
					+		int blen = (j == num_blocks && last_len) ?
 | 
				
			||||||
 | 
					+			last_len : AES_BLOCK_SIZE;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		/* Decryption followed by authentication */
 | 
				
			||||||
 | 
					+		b_0[14] = (j >> 8) & 0xff;
 | 
				
			||||||
 | 
					+		b_0[15] = j & 0xff;
 | 
				
			||||||
 | 
					+		crypto_cipher_encrypt_one(tfm, b, b_0);
 | 
				
			||||||
 | 
					+		for (i = 0; i < blen; i++) {
 | 
				
			||||||
 | 
					+			*pos = *cpos++ ^ b[i];
 | 
				
			||||||
 | 
					+			a[i] ^= *pos++;
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+		crypto_cipher_encrypt_one(tfm, a, a);
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	for (i = 0; i < mic_len; i++) {
 | 
				
			||||||
 | 
					+		if ((mic[i] ^ s_0[i]) != a[i])
 | 
				
			||||||
 | 
					+			return -1;
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
 | 
				
			||||||
 | 
					+						      size_t key_len,
 | 
				
			||||||
 | 
					+						      size_t mic_len)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	struct crypto_cipher *tfm;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
 | 
				
			||||||
 | 
					+	if (!IS_ERR(tfm))
 | 
				
			||||||
 | 
					+		crypto_cipher_setkey(tfm, key, key_len);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return tfm;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+void ieee80211_aes_key_free(struct crypto_cipher *tfm)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	crypto_free_cipher(tfm);
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					--- a/net/mac80211/Kconfig
 | 
				
			||||||
 | 
					+++ b/net/mac80211/Kconfig
 | 
				
			||||||
 | 
					@@ -5,8 +5,6 @@ config MAC80211
 | 
				
			||||||
 | 
					 	depends on CRYPTO
 | 
				
			||||||
 | 
					 	depends on CRYPTO_ARC4
 | 
				
			||||||
 | 
					 	depends on CRYPTO_AES
 | 
				
			||||||
 | 
					-	depends on CRYPTO_CCM
 | 
				
			||||||
 | 
					-	depends on CRYPTO_GCM
 | 
				
			||||||
 | 
					 	depends on CRYPTO_CMAC
 | 
				
			||||||
 | 
					 	depends on CRC32
 | 
				
			||||||
 | 
					 	---help---
 | 
				
			||||||
 | 
					--- a/net/mac80211/aes_gmac.h
 | 
				
			||||||
 | 
					+++ b/net/mac80211/aes_gmac.h
 | 
				
			||||||
 | 
					@@ -15,10 +15,22 @@
 | 
				
			||||||
 | 
					 #define GMAC_MIC_LEN	16
 | 
				
			||||||
 | 
					 #define GMAC_NONCE_LEN	12
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
 | 
				
			||||||
 | 
					-						 size_t key_len);
 | 
				
			||||||
 | 
					-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
 | 
				
			||||||
 | 
					-		       const u8 *data, size_t data_len, u8 *mic);
 | 
				
			||||||
 | 
					-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
 | 
				
			||||||
+static inline struct crypto_aead *
 | 
					+static inline struct crypto_aead *
 | 
				
			||||||
+ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
 | 
					+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
 | 
				
			||||||
+{
 | 
					+{
 | 
				
			||||||
+	return NULL;
 | 
					+	return NULL;
 | 
				
			||||||
+}
 | 
					+}
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
 | 
					+static inline int
 | 
				
			||||||
 | 
					+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
 | 
				
			||||||
 | 
					+		   const u8 *data, size_t data_len, u8 *mic)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
+static inline void
 | 
					+static inline void
 | 
				
			||||||
+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
 | 
					+ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
 | 
				
			||||||
+{
 | 
					+{
 | 
				
			||||||
+}
 | 
					+}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 #endif /* AES_GCM_H */
 | 
					 #endif /* AES_GMAC_H */
 | 
				
			||||||
 | 
					--- a/net/mac80211/key.h
 | 
				
			||||||
 | 
					+++ b/net/mac80211/key.h
 | 
				
			||||||
 | 
					@@ -88,7 +88,7 @@ struct ieee80211_key {
 | 
				
			||||||
 | 
					 			 * Management frames.
 | 
				
			||||||
 | 
					 			 */
 | 
				
			||||||
 | 
					 			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
 | 
				
			||||||
 | 
					-			struct crypto_aead *tfm;
 | 
				
			||||||
 | 
					+			struct crypto_cipher *tfm;
 | 
				
			||||||
 | 
					 			u32 replays; /* dot11RSNAStatsCCMPReplays */
 | 
				
			||||||
 | 
					 		} ccmp;
 | 
				
			||||||
 | 
					 		struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/net/mac80211/cfg.c
 | 
					--- a/net/mac80211/cfg.c
 | 
				
			||||||
+++ b/net/mac80211/cfg.c
 | 
					+++ b/net/mac80211/cfg.c
 | 
				
			||||||
@@ -1056,7 +1056,6 @@ static int ieee80211_stop_ap(struct wiph
 | 
					@@ -1058,7 +1058,6 @@ static int ieee80211_stop_ap(struct wiph
 | 
				
			||||||
 	sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
 | 
					 	sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	__sta_info_flush(sdata, true);
 | 
					 	__sta_info_flush(sdata, true);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@
 | 
				
			|||||||
 static int ieee80211_ifa6_changed(struct notifier_block *nb,
 | 
					 static int ieee80211_ifa6_changed(struct notifier_block *nb,
 | 
				
			||||||
 				  unsigned long data, void *arg)
 | 
					 				  unsigned long data, void *arg)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
@@ -1115,14 +1115,14 @@ int ieee80211_register_hw(struct ieee802
 | 
					@@ -1114,14 +1114,14 @@ int ieee80211_register_hw(struct ieee802
 | 
				
			||||||
 	if (result)
 | 
					 	if (result)
 | 
				
			||||||
 		goto fail_flows;
 | 
					 		goto fail_flows;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -35,7 +35,7 @@
 | 
				
			|||||||
 	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
 | 
					 	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
 | 
				
			||||||
 	result = register_inet6addr_notifier(&local->ifa6_notifier);
 | 
					 	result = register_inet6addr_notifier(&local->ifa6_notifier);
 | 
				
			||||||
 	if (result)
 | 
					 	if (result)
 | 
				
			||||||
@@ -1131,13 +1131,13 @@ int ieee80211_register_hw(struct ieee802
 | 
					@@ -1130,13 +1130,13 @@ int ieee80211_register_hw(struct ieee802
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	return 0;
 | 
					 	return 0;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -52,7 +52,7 @@
 | 
				
			|||||||
  fail_ifa:
 | 
					  fail_ifa:
 | 
				
			||||||
 #endif
 | 
					 #endif
 | 
				
			||||||
 	ieee80211_txq_teardown_flows(local);
 | 
					 	ieee80211_txq_teardown_flows(local);
 | 
				
			||||||
@@ -1167,10 +1167,10 @@ void ieee80211_unregister_hw(struct ieee
 | 
					@@ -1166,10 +1166,10 @@ void ieee80211_unregister_hw(struct ieee
 | 
				
			||||||
 	tasklet_kill(&local->tx_pending_tasklet);
 | 
					 	tasklet_kill(&local->tx_pending_tasklet);
 | 
				
			||||||
 	tasklet_kill(&local->tasklet);
 | 
					 	tasklet_kill(&local->tasklet);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/net/mac80211/cfg.c
 | 
					--- a/net/mac80211/cfg.c
 | 
				
			||||||
+++ b/net/mac80211/cfg.c
 | 
					+++ b/net/mac80211/cfg.c
 | 
				
			||||||
@@ -2212,7 +2212,7 @@ static int ieee80211_scan(struct wiphy *
 | 
					@@ -2215,7 +2215,7 @@ static int ieee80211_scan(struct wiphy *
 | 
				
			||||||
 		 * the  frames sent while scanning on other channel will be
 | 
					 		 * the  frames sent while scanning on other channel will be
 | 
				
			||||||
 		 * lost)
 | 
					 		 * lost)
 | 
				
			||||||
 		 */
 | 
					 		 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 	if (likely(sta)) {
 | 
					 	if (likely(sta)) {
 | 
				
			||||||
 		if (!IS_ERR(sta))
 | 
					 		if (!IS_ERR(sta))
 | 
				
			||||||
 			tx->sta = sta;
 | 
					 			tx->sta = sta;
 | 
				
			||||||
@@ -3434,6 +3434,7 @@ begin:
 | 
					@@ -3468,6 +3468,7 @@ begin:
 | 
				
			||||||
 	tx.local = local;
 | 
					 	tx.local = local;
 | 
				
			||||||
 	tx.skb = skb;
 | 
					 	tx.skb = skb;
 | 
				
			||||||
 	tx.sdata = vif_to_sdata(info->control.vif);
 | 
					 	tx.sdata = vif_to_sdata(info->control.vif);
 | 
				
			||||||
@@ -56,7 +56,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	if (txq->sta)
 | 
					 	if (txq->sta)
 | 
				
			||||||
 		tx.sta = container_of(txq->sta, struct sta_info, sta);
 | 
					 		tx.sta = container_of(txq->sta, struct sta_info, sta);
 | 
				
			||||||
@@ -3756,6 +3757,7 @@ ieee80211_build_data_template(struct iee
 | 
					@@ -3790,6 +3791,7 @@ ieee80211_build_data_template(struct iee
 | 
				
			||||||
 	hdr = (void *)skb->data;
 | 
					 	hdr = (void *)skb->data;
 | 
				
			||||||
 	tx.sta = sta_info_get(sdata, hdr->addr1);
 | 
					 	tx.sta = sta_info_get(sdata, hdr->addr1);
 | 
				
			||||||
 	tx.skb = skb;
 | 
					 	tx.skb = skb;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,9 +23,9 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/include/net/mac80211.h
 | 
					--- a/include/net/mac80211.h
 | 
				
			||||||
+++ b/include/net/mac80211.h
 | 
					+++ b/include/net/mac80211.h
 | 
				
			||||||
@@ -2056,6 +2056,9 @@ struct ieee80211_txq {
 | 
					@@ -2059,6 +2059,9 @@ struct ieee80211_txq {
 | 
				
			||||||
  *	The stack will not do fragmentation.
 | 
					  * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on
 | 
				
			||||||
  *	The callback for @set_frag_threshold should be set as well.
 | 
					  *	TDLS links.
 | 
				
			||||||
  *
 | 
					  *
 | 
				
			||||||
+ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte.
 | 
					+ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte.
 | 
				
			||||||
+ *	Padding will be added after ieee80211_hdr, before IV/LLC.
 | 
					+ *	Padding will be added after ieee80211_hdr, before IV/LLC.
 | 
				
			||||||
@@ -33,27 +33,27 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
 | 
					  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
 enum ieee80211_hw_flags {
 | 
					 enum ieee80211_hw_flags {
 | 
				
			||||||
@@ -2098,6 +2101,7 @@ enum ieee80211_hw_flags {
 | 
					@@ -2102,6 +2105,7 @@ enum ieee80211_hw_flags {
 | 
				
			||||||
 	IEEE80211_HW_TX_FRAG_LIST,
 | 
					 | 
				
			||||||
 	IEEE80211_HW_REPORTS_LOW_ACK,
 | 
					 	IEEE80211_HW_REPORTS_LOW_ACK,
 | 
				
			||||||
 	IEEE80211_HW_SUPPORTS_TX_FRAG,
 | 
					 	IEEE80211_HW_SUPPORTS_TX_FRAG,
 | 
				
			||||||
 | 
					 	IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
 | 
				
			||||||
+	IEEE80211_HW_NEEDS_ALIGNED4_SKBS,
 | 
					+	IEEE80211_HW_NEEDS_ALIGNED4_SKBS,
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	/* keep last, obviously */
 | 
					 	/* keep last, obviously */
 | 
				
			||||||
 	NUM_IEEE80211_HW_FLAGS
 | 
					 	NUM_IEEE80211_HW_FLAGS
 | 
				
			||||||
--- a/net/mac80211/debugfs.c
 | 
					--- a/net/mac80211/debugfs.c
 | 
				
			||||||
+++ b/net/mac80211/debugfs.c
 | 
					+++ b/net/mac80211/debugfs.c
 | 
				
			||||||
@@ -211,6 +211,7 @@ static const char *hw_flag_names[] = {
 | 
					@@ -212,6 +212,7 @@ static const char *hw_flag_names[] = {
 | 
				
			||||||
 	FLAG(TX_FRAG_LIST),
 | 
					 | 
				
			||||||
 	FLAG(REPORTS_LOW_ACK),
 | 
					 	FLAG(REPORTS_LOW_ACK),
 | 
				
			||||||
 	FLAG(SUPPORTS_TX_FRAG),
 | 
					 	FLAG(SUPPORTS_TX_FRAG),
 | 
				
			||||||
 | 
					 	FLAG(SUPPORTS_TDLS_BUFFER_STA),
 | 
				
			||||||
+	FLAG(NEEDS_ALIGNED4_SKBS),
 | 
					+	FLAG(NEEDS_ALIGNED4_SKBS),
 | 
				
			||||||
 #undef FLAG
 | 
					 #undef FLAG
 | 
				
			||||||
 };
 | 
					 };
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
--- a/net/mac80211/ieee80211_i.h
 | 
					--- a/net/mac80211/ieee80211_i.h
 | 
				
			||||||
+++ b/net/mac80211/ieee80211_i.h
 | 
					+++ b/net/mac80211/ieee80211_i.h
 | 
				
			||||||
@@ -1547,6 +1547,29 @@ ieee80211_vif_get_num_mcast_if(struct ie
 | 
					@@ -1548,6 +1548,29 @@ ieee80211_vif_get_num_mcast_if(struct ie
 | 
				
			||||||
 	return -1;
 | 
					 	return -1;
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -85,7 +85,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 				     unsigned int mpdu_len,
 | 
					 				     unsigned int mpdu_len,
 | 
				
			||||||
--- a/net/mac80211/sta_info.h
 | 
					--- a/net/mac80211/sta_info.h
 | 
				
			||||||
+++ b/net/mac80211/sta_info.h
 | 
					+++ b/net/mac80211/sta_info.h
 | 
				
			||||||
@@ -290,7 +290,7 @@ struct ieee80211_fast_tx {
 | 
					@@ -300,7 +300,7 @@ struct ieee80211_fast_tx {
 | 
				
			||||||
 	u8 hdr_len;
 | 
					 	u8 hdr_len;
 | 
				
			||||||
 	u8 sa_offs, da_offs, pn_offs;
 | 
					 	u8 sa_offs, da_offs, pn_offs;
 | 
				
			||||||
 	u8 band;
 | 
					 	u8 band;
 | 
				
			||||||
@@ -147,7 +147,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	if (likely(sta)) {
 | 
					 	if (likely(sta)) {
 | 
				
			||||||
 		if (!IS_ERR(sta))
 | 
					 		if (!IS_ERR(sta))
 | 
				
			||||||
@@ -2150,7 +2149,7 @@ netdev_tx_t ieee80211_monitor_start_xmit
 | 
					@@ -2184,7 +2183,7 @@ netdev_tx_t ieee80211_monitor_start_xmit
 | 
				
			||||||
 		goto fail;
 | 
					 		goto fail;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
 | 
					 	hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
 | 
				
			||||||
@@ -156,7 +156,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	if (skb->len < len_rthdr + hdrlen)
 | 
					 	if (skb->len < len_rthdr + hdrlen)
 | 
				
			||||||
 		goto fail;
 | 
					 		goto fail;
 | 
				
			||||||
@@ -2368,7 +2367,7 @@ static struct sk_buff *ieee80211_build_h
 | 
					@@ -2402,7 +2401,7 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 	struct ieee80211_chanctx_conf *chanctx_conf;
 | 
					 	struct ieee80211_chanctx_conf *chanctx_conf;
 | 
				
			||||||
 	struct ieee80211_sub_if_data *ap_sdata;
 | 
					 	struct ieee80211_sub_if_data *ap_sdata;
 | 
				
			||||||
 	enum nl80211_band band;
 | 
					 	enum nl80211_band band;
 | 
				
			||||||
@@ -165,7 +165,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	if (IS_ERR(sta))
 | 
					 	if (IS_ERR(sta))
 | 
				
			||||||
 		sta = NULL;
 | 
					 		sta = NULL;
 | 
				
			||||||
@@ -2588,6 +2587,9 @@ static struct sk_buff *ieee80211_build_h
 | 
					@@ -2622,6 +2621,9 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 		hdrlen += 2;
 | 
					 		hdrlen += 2;
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -175,7 +175,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 	/*
 | 
					 	/*
 | 
				
			||||||
 	 * Drop unicast frames to unauthorised stations unless they are
 | 
					 	 * Drop unicast frames to unauthorised stations unless they are
 | 
				
			||||||
 	 * EAPOL frames from the local station.
 | 
					 	 * EAPOL frames from the local station.
 | 
				
			||||||
@@ -2668,6 +2670,7 @@ static struct sk_buff *ieee80211_build_h
 | 
					@@ -2702,6 +2704,7 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	skb_pull(skb, skip_header_bytes);
 | 
					 	skb_pull(skb, skip_header_bytes);
 | 
				
			||||||
 	head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
 | 
					 	head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
 | 
				
			||||||
@@ -183,7 +183,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	/*
 | 
					 	/*
 | 
				
			||||||
 	 * So we need to modify the skb header and hence need a copy of
 | 
					 	 * So we need to modify the skb header and hence need a copy of
 | 
				
			||||||
@@ -2700,6 +2703,9 @@ static struct sk_buff *ieee80211_build_h
 | 
					@@ -2734,6 +2737,9 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 		memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
 | 
					 		memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
 | 
				
			||||||
 #endif
 | 
					 #endif
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -193,7 +193,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 	if (ieee80211_is_data_qos(fc)) {
 | 
					 	if (ieee80211_is_data_qos(fc)) {
 | 
				
			||||||
 		__le16 *qos_control;
 | 
					 		__le16 *qos_control;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -2875,6 +2881,9 @@ void ieee80211_check_fast_xmit(struct st
 | 
					@@ -2909,6 +2915,9 @@ void ieee80211_check_fast_xmit(struct st
 | 
				
			||||||
 		fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
 | 
					 		fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -203,7 +203,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			|||||||
 	/* We store the key here so there's no point in using rcu_dereference()
 | 
					 	/* We store the key here so there's no point in using rcu_dereference()
 | 
				
			||||||
 	 * but that's fine because the code that changes the pointers will call
 | 
					 	 * but that's fine because the code that changes the pointers will call
 | 
				
			||||||
 	 * this function after doing so. For a single CPU that would be enough,
 | 
					 	 * this function after doing so. For a single CPU that would be enough,
 | 
				
			||||||
@@ -3461,7 +3470,7 @@ begin:
 | 
					@@ -3495,7 +3504,7 @@ begin:
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 		if (tx.key &&
 | 
					 		if (tx.key &&
 | 
				
			||||||
 		    (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
 | 
					 		    (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ in the hope that we've fixed all the performance problems now.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
@@ -8286,15 +8286,6 @@ int ath10k_mac_register(struct ath10k *a
 | 
					@@ -8319,15 +8319,6 @@ int ath10k_mac_register(struct ath10k *a
 | 
				
			||||||
 			ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
 | 
					 			ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					From: Brian Norris <briannorris@chromium.org>
 | 
				
			||||||
 | 
					Date: Thu, 19 Oct 2017 11:45:19 -0700
 | 
				
			||||||
 | 
					Subject: [PATCH] ath10k: fix build errors with !CONFIG_PM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Build errors have been reported with CONFIG_PM=n:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					drivers/net/wireless/ath/ath10k/pci.c:3416:8: error: implicit
 | 
				
			||||||
 | 
					declaration of function 'ath10k_pci_suspend'
 | 
				
			||||||
 | 
					[-Werror=implicit-function-declaration]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					drivers/net/wireless/ath/ath10k/pci.c:3428:8: error: implicit
 | 
				
			||||||
 | 
					declaration of function 'ath10k_pci_resume'
 | 
				
			||||||
 | 
					[-Werror=implicit-function-declaration]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These are caused by the combination of the following two commits:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					6af1de2e4ec4 ("ath10k: mark PM functions as __maybe_unused")
 | 
				
			||||||
 | 
					96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but
 | 
				
			||||||
 | 
					disabled")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Both build fine on their own.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					But now that ath10k_pci_pm_{suspend,resume}() is compiled
 | 
				
			||||||
 | 
					unconditionally, we should also compile ath10k_pci_{suspend,resume}()
 | 
				
			||||||
 | 
					unconditionally.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And drop the #ifdef around ath10k_pci_hif_{suspend,resume}() too; they
 | 
				
			||||||
 | 
					are trivial (empty), so we're not saving much space by compiling them
 | 
				
			||||||
 | 
					out. And the alternatives would be to sprinkle more __maybe_unused, or
 | 
				
			||||||
 | 
					spread the #ifdef's further.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Build tested with the following combinations:
 | 
				
			||||||
 | 
					CONFIG_PM=y && CONFIG_PM_SLEEP=y
 | 
				
			||||||
 | 
					CONFIG_PM=y && CONFIG_PM_SLEEP=n
 | 
				
			||||||
 | 
					CONFIG_PM=n
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixes: 96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but disabled")
 | 
				
			||||||
 | 
					Fixes: 096ad2a15fd8 ("Merge branch 'ath-next'")
 | 
				
			||||||
 | 
					Signed-off-by: Brian Norris <briannorris@chromium.org>
 | 
				
			||||||
 | 
					Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- a/drivers/net/wireless/ath/ath10k/pci.c
 | 
				
			||||||
 | 
					+++ b/drivers/net/wireless/ath/ath10k/pci.c
 | 
				
			||||||
 | 
					@@ -2577,8 +2577,6 @@ void ath10k_pci_hif_power_down(struct at
 | 
				
			||||||
 | 
					 	 */
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-#ifdef CONFIG_PM
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					 static int ath10k_pci_hif_suspend(struct ath10k *ar)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	/* Nothing to do; the important stuff is in the driver suspend. */
 | 
				
			||||||
 | 
					@@ -2627,7 +2625,6 @@ static int ath10k_pci_resume(struct ath1
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	return ret;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					-#endif
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static bool ath10k_pci_validate_cal(void *data, size_t size)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					@@ -2782,10 +2779,8 @@ static const struct ath10k_hif_ops ath10
 | 
				
			||||||
 | 
					 	.power_down		= ath10k_pci_hif_power_down,
 | 
				
			||||||
 | 
					 	.read32			= ath10k_pci_read32,
 | 
				
			||||||
 | 
					 	.write32		= ath10k_pci_write32,
 | 
				
			||||||
 | 
					-#ifdef CONFIG_PM
 | 
				
			||||||
 | 
					 	.suspend		= ath10k_pci_hif_suspend,
 | 
				
			||||||
 | 
					 	.resume			= ath10k_pci_hif_resume,
 | 
				
			||||||
 | 
					-#endif
 | 
				
			||||||
 | 
					 	.fetch_cal_eeprom	= ath10k_pci_hif_fetch_cal_eeprom,
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					From: Christian Lamparter <chunkeey@gmail.com>
 | 
				
			||||||
 | 
					Date: Wed, 1 Nov 2017 21:01:57 +0100
 | 
				
			||||||
 | 
					Subject: [PATCH] ath10k: fix recent bandwidth conversion bug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The commit "cfg80211: make RATE_INFO_BW_20 the default" changed
 | 
				
			||||||
 | 
					the index of RATE_INFO_BW_20, but the updates to ath10k missed
 | 
				
			||||||
 | 
					the special bandwidth calculation case in
 | 
				
			||||||
 | 
					ath10k_update_per_peer_tx_stats().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixes: 842be75c77cb ("cfg80211: make RATE_INFO_BW_20 the default")
 | 
				
			||||||
 | 
					Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
 | 
				
			||||||
 | 
					Patchwork-Id: 10037035
 | 
				
			||||||
 | 
					Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
 | 
				
			||||||
 | 
					+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
 | 
				
			||||||
 | 
					@@ -592,6 +592,9 @@ struct amsdu_subframe_hdr {
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 #define GROUP_ID_IS_SU_MIMO(x) ((x) == 0 || (x) == 63)
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+static const u8 ath10k_bw_to_mac80211[] = { RATE_INFO_BW_20, RATE_INFO_BW_40,
 | 
				
			||||||
 | 
					+	RATE_INFO_BW_80, RATE_INFO_BW_160 };
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 static void ath10k_htt_rx_h_rates(struct ath10k *ar,
 | 
				
			||||||
 | 
					 				  struct ieee80211_rx_status *status,
 | 
				
			||||||
 | 
					 				  struct htt_rx_desc *rxd)
 | 
				
			||||||
 | 
					@@ -694,23 +697,7 @@ static void ath10k_htt_rx_h_rates(struct
 | 
				
			||||||
 | 
					 		if (sgi)
 | 
				
			||||||
 | 
					 			status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-		switch (bw) {
 | 
				
			||||||
 | 
					-		/* 20MHZ */
 | 
				
			||||||
 | 
					-		case 0:
 | 
				
			||||||
 | 
					-			break;
 | 
				
			||||||
 | 
					-		/* 40MHZ */
 | 
				
			||||||
 | 
					-		case 1:
 | 
				
			||||||
 | 
					-			status->bw = RATE_INFO_BW_40;
 | 
				
			||||||
 | 
					-			break;
 | 
				
			||||||
 | 
					-		/* 80MHZ */
 | 
				
			||||||
 | 
					-		case 2:
 | 
				
			||||||
 | 
					-			status->bw = RATE_INFO_BW_80;
 | 
				
			||||||
 | 
					-			break;
 | 
				
			||||||
 | 
					-		case 3:
 | 
				
			||||||
 | 
					-			status->bw = RATE_INFO_BW_160;
 | 
				
			||||||
 | 
					-			break;
 | 
				
			||||||
 | 
					-		}
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					+		status->bw = ath10k_bw_to_mac80211[bw];
 | 
				
			||||||
 | 
					 		status->encoding = RX_ENC_VHT;
 | 
				
			||||||
 | 
					 		break;
 | 
				
			||||||
 | 
					 	default:
 | 
				
			||||||
 | 
					@@ -2297,7 +2284,7 @@ ath10k_update_per_peer_tx_stats(struct a
 | 
				
			||||||
 | 
					 		arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	arsta->txrate.nss = txrate.nss;
 | 
				
			||||||
 | 
					-	arsta->txrate.bw = txrate.bw + RATE_INFO_BW_20;
 | 
				
			||||||
 | 
					+	arsta->txrate.bw = ath10k_bw_to_mac80211[txrate.bw];
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static void ath10k_htt_fetch_peer_stats(struct ath10k *ar,
 | 
				
			||||||
@@ -1,81 +0,0 @@
 | 
				
			|||||||
From fdf7cb4185b60c68e1a75e61691c4afdc15dea0e Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Johannes Berg <johannes.berg@intel.com>
 | 
					 | 
				
			||||||
Date: Tue, 5 Sep 2017 14:54:54 +0200
 | 
					 | 
				
			||||||
Subject: [PATCH] mac80211: accept key reinstall without changing anything
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
When a key is reinstalled we can reset the replay counters
 | 
					 | 
				
			||||||
etc. which can lead to nonce reuse and/or replay detection
 | 
					 | 
				
			||||||
being impossible, breaking security properties, as described
 | 
					 | 
				
			||||||
in the "KRACK attacks".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In particular, CVE-2017-13080 applies to GTK rekeying that
 | 
					 | 
				
			||||||
happened in firmware while the host is in D3, with the second
 | 
					 | 
				
			||||||
part of the attack being done after the host wakes up. In
 | 
					 | 
				
			||||||
this case, the wpa_supplicant mitigation isn't sufficient
 | 
					 | 
				
			||||||
since wpa_supplicant doesn't know the GTK material.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In case this happens, simply silently accept the new key
 | 
					 | 
				
			||||||
coming from userspace but don't take any action on it since
 | 
					 | 
				
			||||||
it's the same key; this keeps the PN replay counters intact.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 net/mac80211/key.c | 21 +++++++++++++++++----
 | 
					 | 
				
			||||||
 1 file changed, 17 insertions(+), 4 deletions(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
 | 
					 | 
				
			||||||
index a98fc2b5e0dc..ae995c8480db 100644
 | 
					 | 
				
			||||||
--- a/net/mac80211/key.c
 | 
					 | 
				
			||||||
+++ b/net/mac80211/key.c
 | 
					 | 
				
			||||||
@@ -4,7 +4,7 @@
 | 
					 | 
				
			||||||
  * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
 | 
					 | 
				
			||||||
  * Copyright 2007-2008	Johannes Berg <johannes@sipsolutions.net>
 | 
					 | 
				
			||||||
  * Copyright 2013-2014  Intel Mobile Communications GmbH
 | 
					 | 
				
			||||||
- * Copyright 2015	Intel Deutschland GmbH
 | 
					 | 
				
			||||||
+ * Copyright 2015-2017	Intel Deutschland GmbH
 | 
					 | 
				
			||||||
  *
 | 
					 | 
				
			||||||
  * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
  * it under the terms of the GNU General Public License version 2 as
 | 
					 | 
				
			||||||
@@ -620,9 +620,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
 | 
					 | 
				
			||||||
 	idx = key->conf.keyidx;
 | 
					 | 
				
			||||||
-	key->local = sdata->local;
 | 
					 | 
				
			||||||
-	key->sdata = sdata;
 | 
					 | 
				
			||||||
-	key->sta = sta;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	mutex_lock(&sdata->local->key_mtx);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -633,6 +630,21 @@ int ieee80211_key_link(struct ieee80211_key *key,
 | 
					 | 
				
			||||||
 	else
 | 
					 | 
				
			||||||
 		old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+	/*
 | 
					 | 
				
			||||||
+	 * Silently accept key re-installation without really installing the
 | 
					 | 
				
			||||||
+	 * new version of the key to avoid nonce reuse or replay issues.
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	if (old_key && key->conf.keylen == old_key->conf.keylen &&
 | 
					 | 
				
			||||||
+	    !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) {
 | 
					 | 
				
			||||||
+		ieee80211_key_free_unused(key);
 | 
					 | 
				
			||||||
+		ret = 0;
 | 
					 | 
				
			||||||
+		goto out;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	key->local = sdata->local;
 | 
					 | 
				
			||||||
+	key->sdata = sdata;
 | 
					 | 
				
			||||||
+	key->sta = sta;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	increment_tailroom_need_count(sdata);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
 | 
					 | 
				
			||||||
@@ -648,6 +660,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
 | 
					 | 
				
			||||||
 		ret = 0;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+ out:
 | 
					 | 
				
			||||||
 	mutex_unlock(&sdata->local->key_mtx);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	return ret;
 | 
					 | 
				
			||||||
-- 
 | 
					 | 
				
			||||||
2.13.6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,33 +0,0 @@
 | 
				
			|||||||
From 2bdd713b92a9cade239d3c7d15205a09f556624d Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
 | 
					 | 
				
			||||||
Date: Tue, 17 Oct 2017 20:32:07 +0200
 | 
					 | 
				
			||||||
Subject: [PATCH] mac80211: use constant time comparison with keys
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Otherwise we risk leaking information via timing side channel.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Fixes: fdf7cb4185b6 ("mac80211: accept key reinstall without changing anything")
 | 
					 | 
				
			||||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
 | 
					 | 
				
			||||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 net/mac80211/key.c | 3 ++-
 | 
					 | 
				
			||||||
 1 file changed, 2 insertions(+), 1 deletion(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/net/mac80211/key.c
 | 
					 | 
				
			||||||
+++ b/net/mac80211/key.c
 | 
					 | 
				
			||||||
@@ -19,6 +19,7 @@
 | 
					 | 
				
			||||||
 #include <linux/slab.h>
 | 
					 | 
				
			||||||
 #include <linux/export.h>
 | 
					 | 
				
			||||||
 #include <net/mac80211.h>
 | 
					 | 
				
			||||||
+#include <crypto/algapi.h>
 | 
					 | 
				
			||||||
 #include <asm/unaligned.h>
 | 
					 | 
				
			||||||
 #include "ieee80211_i.h"
 | 
					 | 
				
			||||||
 #include "driver-ops.h"
 | 
					 | 
				
			||||||
@@ -635,7 +636,7 @@ int ieee80211_key_link(struct ieee80211_
 | 
					 | 
				
			||||||
 	 * new version of the key to avoid nonce reuse or replay issues.
 | 
					 | 
				
			||||||
 	 */
 | 
					 | 
				
			||||||
 	if (old_key && key->conf.keylen == old_key->conf.keylen &&
 | 
					 | 
				
			||||||
-	    !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) {
 | 
					 | 
				
			||||||
+	    !crypto_memneq(key->conf.key, old_key->conf.key, key->conf.keylen)) {
 | 
					 | 
				
			||||||
 		ieee80211_key_free_unused(key);
 | 
					 | 
				
			||||||
 		ret = 0;
 | 
					 | 
				
			||||||
 		goto out;
 | 
					 | 
				
			||||||
@@ -1,73 +0,0 @@
 | 
				
			|||||||
From cfbb0d90a7abb289edc91833d0905931f8805f12 Mon Sep 17 00:00:00 2001
 | 
					 | 
				
			||||||
From: Johannes Berg <johannes.berg@intel.com>
 | 
					 | 
				
			||||||
Date: Tue, 24 Oct 2017 21:12:13 +0200
 | 
					 | 
				
			||||||
Subject: [PATCH] mac80211: don't compare TKIP TX MIC key in reinstall prevention
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For the reinstall prevention, the code I had added compares the
 | 
					 | 
				
			||||||
whole key. It turns out though that iwlwifi firmware doesn't
 | 
					 | 
				
			||||||
provide the TKIP TX MIC key as it's not needed in client mode,
 | 
					 | 
				
			||||||
and thus the comparison will always return false.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For client mode, thus always zero out the TX MIC key part before
 | 
					 | 
				
			||||||
doing the comparison in order to avoid accepting the reinstall
 | 
					 | 
				
			||||||
of the key with identical encryption and RX MIC key, but not the
 | 
					 | 
				
			||||||
same TX MIC key (since the supplicant provides the real one.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Fixes: fdf7cb4185b6 ("mac80211: accept key reinstall without changing anything")
 | 
					 | 
				
			||||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 net/mac80211/key.c | 36 ++++++++++++++++++++++++++++++++++--
 | 
					 | 
				
			||||||
 1 file changed, 34 insertions(+), 2 deletions(-)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/net/mac80211/key.c
 | 
					 | 
				
			||||||
+++ b/net/mac80211/key.c
 | 
					 | 
				
			||||||
@@ -610,6 +610,39 @@ void ieee80211_key_free_unused(struct ie
 | 
					 | 
				
			||||||
 	ieee80211_key_free_common(key);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+static bool ieee80211_key_identical(struct ieee80211_sub_if_data *sdata,
 | 
					 | 
				
			||||||
+				    struct ieee80211_key *old,
 | 
					 | 
				
			||||||
+				    struct ieee80211_key *new)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	u8 tkip_old[WLAN_KEY_LEN_TKIP], tkip_new[WLAN_KEY_LEN_TKIP];
 | 
					 | 
				
			||||||
+	u8 *tk_old, *tk_new;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (!old || new->conf.keylen != old->conf.keylen)
 | 
					 | 
				
			||||||
+		return false;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	tk_old = old->conf.key;
 | 
					 | 
				
			||||||
+	tk_new = new->conf.key;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	/*
 | 
					 | 
				
			||||||
+	 * In station mode, don't compare the TX MIC key, as it's never used
 | 
					 | 
				
			||||||
+	 * and offloaded rekeying may not care to send it to the host. This
 | 
					 | 
				
			||||||
+	 * is the case in iwlwifi, for example.
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	if (sdata->vif.type == NL80211_IFTYPE_STATION &&
 | 
					 | 
				
			||||||
+	    new->conf.cipher == WLAN_CIPHER_SUITE_TKIP &&
 | 
					 | 
				
			||||||
+	    new->conf.keylen == WLAN_KEY_LEN_TKIP &&
 | 
					 | 
				
			||||||
+	    !(new->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
 | 
					 | 
				
			||||||
+		memcpy(tkip_old, tk_old, WLAN_KEY_LEN_TKIP);
 | 
					 | 
				
			||||||
+		memcpy(tkip_new, tk_new, WLAN_KEY_LEN_TKIP);
 | 
					 | 
				
			||||||
+		memset(tkip_old + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 0, 8);
 | 
					 | 
				
			||||||
+		memset(tkip_new + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 0, 8);
 | 
					 | 
				
			||||||
+		tk_old = tkip_old;
 | 
					 | 
				
			||||||
+		tk_new = tkip_new;
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return !crypto_memneq(tk_old, tk_new, new->conf.keylen);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 int ieee80211_key_link(struct ieee80211_key *key,
 | 
					 | 
				
			||||||
 		       struct ieee80211_sub_if_data *sdata,
 | 
					 | 
				
			||||||
 		       struct sta_info *sta)
 | 
					 | 
				
			||||||
@@ -635,8 +668,7 @@ int ieee80211_key_link(struct ieee80211_
 | 
					 | 
				
			||||||
 	 * Silently accept key re-installation without really installing the
 | 
					 | 
				
			||||||
 	 * new version of the key to avoid nonce reuse or replay issues.
 | 
					 | 
				
			||||||
 	 */
 | 
					 | 
				
			||||||
-	if (old_key && key->conf.keylen == old_key->conf.keylen &&
 | 
					 | 
				
			||||||
-	    !crypto_memneq(key->conf.key, old_key->conf.key, key->conf.keylen)) {
 | 
					 | 
				
			||||||
+	if (ieee80211_key_identical(sdata, old_key, key)) {
 | 
					 | 
				
			||||||
 		ieee80211_key_free_unused(key);
 | 
					 | 
				
			||||||
 		ret = 0;
 | 
					 | 
				
			||||||
 		goto out;
 | 
					 | 
				
			||||||
@@ -106,7 +106,7 @@
 | 
				
			|||||||
 	---help---
 | 
					 	---help---
 | 
				
			||||||
--- a/local-symbols
 | 
					--- a/local-symbols
 | 
				
			||||||
+++ b/local-symbols
 | 
					+++ b/local-symbols
 | 
				
			||||||
@@ -82,6 +82,7 @@ ADM8211=
 | 
					@@ -87,6 +87,7 @@ ADM8211=
 | 
				
			||||||
 ATH_COMMON=
 | 
					 ATH_COMMON=
 | 
				
			||||||
 WLAN_VENDOR_ATH=
 | 
					 WLAN_VENDOR_ATH=
 | 
				
			||||||
 ATH_DEBUG=
 | 
					 ATH_DEBUG=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/net/wireless/reg.c
 | 
					--- a/net/wireless/reg.c
 | 
				
			||||||
+++ b/net/wireless/reg.c
 | 
					+++ b/net/wireless/reg.c
 | 
				
			||||||
@@ -2497,6 +2497,8 @@ void regulatory_hint_country_ie(struct w
 | 
					@@ -2860,6 +2860,8 @@ void regulatory_hint_country_ie(struct w
 | 
				
			||||||
 	enum environment_cap env = ENVIRON_ANY;
 | 
					 	enum environment_cap env = ENVIRON_ANY;
 | 
				
			||||||
 	struct regulatory_request *request = NULL, *lr;
 | 
					 	struct regulatory_request *request = NULL, *lr;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -9,7 +9,7 @@
 | 
				
			|||||||
 	/* IE len must be evenly divisible by 2 */
 | 
					 	/* IE len must be evenly divisible by 2 */
 | 
				
			||||||
 	if (country_ie_len & 0x01)
 | 
					 	if (country_ie_len & 0x01)
 | 
				
			||||||
 		return;
 | 
					 		return;
 | 
				
			||||||
@@ -2703,6 +2705,7 @@ static void restore_regulatory_settings(
 | 
					@@ -3066,6 +3068,7 @@ static void restore_regulatory_settings(
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 void regulatory_hint_disconnect(void)
 | 
					 void regulatory_hint_disconnect(void)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@
 | 
				
			|||||||
 	u8 ps_dtim_period;
 | 
					 	u8 ps_dtim_period;
 | 
				
			||||||
--- a/include/uapi/linux/nl80211.h
 | 
					--- a/include/uapi/linux/nl80211.h
 | 
				
			||||||
+++ b/include/uapi/linux/nl80211.h
 | 
					+++ b/include/uapi/linux/nl80211.h
 | 
				
			||||||
@@ -2149,6 +2149,9 @@ enum nl80211_commands {
 | 
					@@ -2153,6 +2153,9 @@ enum nl80211_commands {
 | 
				
			||||||
  * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
 | 
					  * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
 | 
				
			||||||
  * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
 | 
					  * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
 | 
				
			||||||
  *
 | 
					  *
 | 
				
			||||||
@@ -46,7 +46,7 @@
 | 
				
			|||||||
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 | 
					  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 | 
				
			||||||
  * @NL80211_ATTR_MAX: highest attribute number currently defined
 | 
					  * @NL80211_ATTR_MAX: highest attribute number currently defined
 | 
				
			||||||
  * @__NL80211_ATTR_AFTER_LAST: internal use
 | 
					  * @__NL80211_ATTR_AFTER_LAST: internal use
 | 
				
			||||||
@@ -2575,6 +2578,8 @@ enum nl80211_attrs {
 | 
					@@ -2579,6 +2582,8 @@ enum nl80211_attrs {
 | 
				
			||||||
 	NL80211_ATTR_PMKR0_NAME,
 | 
					 	NL80211_ATTR_PMKR0_NAME,
 | 
				
			||||||
 	NL80211_ATTR_PORT_AUTHORIZED,
 | 
					 	NL80211_ATTR_PORT_AUTHORIZED,
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -57,7 +57,7 @@
 | 
				
			|||||||
 	__NL80211_ATTR_AFTER_LAST,
 | 
					 	__NL80211_ATTR_AFTER_LAST,
 | 
				
			||||||
--- a/net/mac80211/cfg.c
 | 
					--- a/net/mac80211/cfg.c
 | 
				
			||||||
+++ b/net/mac80211/cfg.c
 | 
					+++ b/net/mac80211/cfg.c
 | 
				
			||||||
@@ -2444,6 +2444,19 @@ static int ieee80211_get_tx_power(struct
 | 
					@@ -2447,6 +2447,19 @@ static int ieee80211_get_tx_power(struct
 | 
				
			||||||
 	return 0;
 | 
					 	return 0;
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -77,7 +77,7 @@
 | 
				
			|||||||
 static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
 | 
					 static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
 | 
				
			||||||
 				  const u8 *addr)
 | 
					 				  const u8 *addr)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
@@ -3717,6 +3730,7 @@ const struct cfg80211_ops mac80211_confi
 | 
					@@ -3720,6 +3733,7 @@ const struct cfg80211_ops mac80211_confi
 | 
				
			||||||
 	.set_wiphy_params = ieee80211_set_wiphy_params,
 | 
					 	.set_wiphy_params = ieee80211_set_wiphy_params,
 | 
				
			||||||
 	.set_tx_power = ieee80211_set_tx_power,
 | 
					 	.set_tx_power = ieee80211_set_tx_power,
 | 
				
			||||||
 	.get_tx_power = ieee80211_get_tx_power,
 | 
					 	.get_tx_power = ieee80211_get_tx_power,
 | 
				
			||||||
@@ -87,7 +87,7 @@
 | 
				
			|||||||
 	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
 | 
					 	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
 | 
				
			||||||
--- a/net/mac80211/ieee80211_i.h
 | 
					--- a/net/mac80211/ieee80211_i.h
 | 
				
			||||||
+++ b/net/mac80211/ieee80211_i.h
 | 
					+++ b/net/mac80211/ieee80211_i.h
 | 
				
			||||||
@@ -1347,6 +1347,7 @@ struct ieee80211_local {
 | 
					@@ -1348,6 +1348,7 @@ struct ieee80211_local {
 | 
				
			||||||
 	int dynamic_ps_forced_timeout;
 | 
					 	int dynamic_ps_forced_timeout;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	int user_power_level; /* in dBm, for all interfaces */
 | 
					 	int user_power_level; /* in dBm, for all interfaces */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -125,7 +125,7 @@
 | 
				
			|||||||
 		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
 | 
					 		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath9k/main.c
 | 
					--- a/drivers/net/wireless/ath/ath9k/main.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
 | 
					+++ b/drivers/net/wireless/ath/ath9k/main.c
 | 
				
			||||||
@@ -527,6 +527,11 @@ irqreturn_t ath_isr(int irq, void *dev)
 | 
					@@ -528,6 +528,11 @@ irqreturn_t ath_isr(int irq, void *dev)
 | 
				
			||||||
 	if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
 | 
					 	if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
 | 
				
			||||||
 		return IRQ_HANDLED;
 | 
					 		return IRQ_HANDLED;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@
 | 
				
			|||||||
 	struct ath_hw *ah = sc->sc_ah;
 | 
					 	struct ath_hw *ah = sc->sc_ah;
 | 
				
			||||||
 	struct ath_common *common = ath9k_hw_common(ah);
 | 
					 	struct ath_common *common = ath9k_hw_common(ah);
 | 
				
			||||||
 	struct ieee80211_hw *hw = sc->hw;
 | 
					 	struct ieee80211_hw *hw = sc->hw;
 | 
				
			||||||
@@ -41,6 +44,11 @@ static int ath_set_channel(struct ath_so
 | 
					@@ -42,6 +45,11 @@ static int ath_set_channel(struct ath_so
 | 
				
			||||||
 	ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
 | 
					 	ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
 | 
				
			||||||
 		chan->center_freq, chandef->width);
 | 
					 		chan->center_freq, chandef->width);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -27,7 +27,7 @@
 | 
				
			|||||||
+	}
 | 
					+	}
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
 	/* update survey stats for the old channel before switching */
 | 
					 	/* update survey stats for the old channel before switching */
 | 
				
			||||||
 	spin_lock_bh(&common->cc_lock);
 | 
					 	spin_lock_irqsave(&common->cc_lock, flags);
 | 
				
			||||||
 	ath_update_survey_stats(sc);
 | 
					 	ath_update_survey_stats(sc);
 | 
				
			||||||
--- /dev/null
 | 
					--- /dev/null
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath9k/hsr.c
 | 
					+++ b/drivers/net/wireless/ath/ath9k/hsr.c
 | 
				
			||||||
@@ -343,7 +343,7 @@
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 u8 ath9k_parse_mpdudensity(u8 mpdudensity)
 | 
					 u8 ath9k_parse_mpdudensity(u8 mpdudensity)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
@@ -648,6 +650,7 @@ void ath_reset_work(struct work_struct *
 | 
					@@ -649,6 +651,7 @@ void ath_reset_work(struct work_struct *
 | 
				
			||||||
 static int ath9k_start(struct ieee80211_hw *hw)
 | 
					 static int ath9k_start(struct ieee80211_hw *hw)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	struct ath_softc *sc = hw->priv;
 | 
					 	struct ath_softc *sc = hw->priv;
 | 
				
			||||||
@@ -351,7 +351,7 @@
 | 
				
			|||||||
 	struct ath_hw *ah = sc->sc_ah;
 | 
					 	struct ath_hw *ah = sc->sc_ah;
 | 
				
			||||||
 	struct ath_common *common = ath9k_hw_common(ah);
 | 
					 	struct ath_common *common = ath9k_hw_common(ah);
 | 
				
			||||||
 	struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
 | 
					 	struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
 | 
				
			||||||
@@ -726,6 +729,11 @@ static int ath9k_start(struct ieee80211_
 | 
					@@ -727,6 +730,11 @@ static int ath9k_start(struct ieee80211_
 | 
				
			||||||
 					  AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 | 
					 					  AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -386,7 +386,7 @@
 | 
				
			|||||||
 #endif /* _LINUX_ATH9K_PLATFORM_H */
 | 
					 #endif /* _LINUX_ATH9K_PLATFORM_H */
 | 
				
			||||||
--- a/local-symbols
 | 
					--- a/local-symbols
 | 
				
			||||||
+++ b/local-symbols
 | 
					+++ b/local-symbols
 | 
				
			||||||
@@ -109,6 +109,7 @@ ATH9K_WOW=
 | 
					@@ -114,6 +114,7 @@ ATH9K_WOW=
 | 
				
			||||||
 ATH9K_RFKILL=
 | 
					 ATH9K_RFKILL=
 | 
				
			||||||
 ATH9K_CHANNEL_CONTEXT=
 | 
					 ATH9K_CHANNEL_CONTEXT=
 | 
				
			||||||
 ATH9K_PCOEM=
 | 
					 ATH9K_PCOEM=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/local-symbols
 | 
					--- a/local-symbols
 | 
				
			||||||
+++ b/local-symbols
 | 
					+++ b/local-symbols
 | 
				
			||||||
@@ -291,6 +291,7 @@ RT2X00_LIB_FIRMWARE=
 | 
					@@ -296,6 +296,7 @@ RT2X00_LIB_FIRMWARE=
 | 
				
			||||||
 RT2X00_LIB_CRYPTO=
 | 
					 RT2X00_LIB_CRYPTO=
 | 
				
			||||||
 RT2X00_LIB_LEDS=
 | 
					 RT2X00_LIB_LEDS=
 | 
				
			||||||
 RT2X00_LIB_DEBUGFS=
 | 
					 RT2X00_LIB_DEBUGFS=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/drivers/net/wireless/marvell/libertas/cfg.c
 | 
					--- a/drivers/net/wireless/marvell/libertas/cfg.c
 | 
				
			||||||
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
 | 
					+++ b/drivers/net/wireless/marvell/libertas/cfg.c
 | 
				
			||||||
@@ -2043,6 +2043,8 @@ struct wireless_dev *lbs_cfg_alloc(struc
 | 
					@@ -2040,6 +2040,8 @@ struct wireless_dev *lbs_cfg_alloc(struc
 | 
				
			||||||
 		goto err_wiphy_new;
 | 
					 		goto err_wiphy_new;
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
  err_wiphy_new:
 | 
					  err_wiphy_new:
 | 
				
			||||||
--- a/drivers/net/wireless/marvell/libertas/main.c
 | 
					--- a/drivers/net/wireless/marvell/libertas/main.c
 | 
				
			||||||
+++ b/drivers/net/wireless/marvell/libertas/main.c
 | 
					+++ b/drivers/net/wireless/marvell/libertas/main.c
 | 
				
			||||||
@@ -933,6 +933,7 @@ struct lbs_private *lbs_add_card(void *c
 | 
					@@ -930,6 +930,7 @@ struct lbs_private *lbs_add_card(void *c
 | 
				
			||||||
 		goto err_adapter;
 | 
					 		goto err_adapter;
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/drivers/net/wireless/marvell/libertas/cfg.c
 | 
					--- a/drivers/net/wireless/marvell/libertas/cfg.c
 | 
				
			||||||
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
 | 
					+++ b/drivers/net/wireless/marvell/libertas/cfg.c
 | 
				
			||||||
@@ -2119,6 +2119,8 @@ int lbs_cfg_register(struct lbs_private
 | 
					@@ -2116,6 +2116,8 @@ int lbs_cfg_register(struct lbs_private
 | 
				
			||||||
 	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 | 
					 	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 | 
				
			||||||
 	wdev->wiphy->reg_notifier = lbs_reg_notifier;
 | 
					 	wdev->wiphy->reg_notifier = lbs_reg_notifier;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
@@ -2445,6 +2445,16 @@ int ath10k_core_register(struct ath10k *
 | 
					@@ -2458,6 +2458,16 @@ int ath10k_core_register(struct ath10k *
 | 
				
			||||||
 	ar->chip_id = chip_id;
 | 
					 	ar->chip_id = chip_id;
 | 
				
			||||||
 	queue_work(ar->workqueue, &ar->register_work);
 | 
					 	queue_work(ar->workqueue, &ar->register_work);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
@@ -8067,6 +8067,21 @@ static int ath10k_mac_init_rd(struct ath
 | 
					@@ -8080,6 +8080,21 @@ static int ath10k_mac_init_rd(struct ath
 | 
				
			||||||
 	return 0;
 | 
					 	return 0;
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -22,7 +22,7 @@
 | 
				
			|||||||
 int ath10k_mac_register(struct ath10k *ar)
 | 
					 int ath10k_mac_register(struct ath10k *ar)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	static const u32 cipher_suites[] = {
 | 
					 	static const u32 cipher_suites[] = {
 | 
				
			||||||
@@ -8308,6 +8323,12 @@ int ath10k_mac_register(struct ath10k *a
 | 
					@@ -8352,6 +8367,12 @@ int ath10k_mac_register(struct ath10k *a
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
 | 
					 	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
@@ -757,7 +757,7 @@ static int ath10k_core_get_board_id_from
 | 
					@@ -770,7 +770,7 @@ static int ath10k_core_get_board_id_from
 | 
				
			||||||
 	if (ret) {
 | 
					 	if (ret) {
 | 
				
			||||||
 		ath10k_err(ar, "could not execute otp for board id check: %d\n",
 | 
					 		ath10k_err(ar, "could not execute otp for board id check: %d\n",
 | 
				
			||||||
 			   ret);
 | 
					 			   ret);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user