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:
parent
a8d751c243
commit
f9fa266faf
30 changed files with 723 additions and 1815 deletions
|
@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
|
|||
|
||||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=2017-10-06
|
||||
PKG_VERSION:=2017-11-01
|
||||
PKG_RELEASE:=1
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
|
||||
PKG_HASH:=194786b7635f36b9ce280fd2319f6a4feeff209175e330ddbcbe789a3b4540a5
|
||||
PKG_HASH:=8437ab7886b988c8152e7a4db30b7f41009e49a3b2cb863edd05da1ecd7eb05a
|
||||
|
||||
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
|
||||
|
@ -87,7 +87,7 @@ endef
|
|||
define KernelPackage/cfg80211
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=cfg80211 - wireless configuration API
|
||||
DEPENDS+= +iw
|
||||
DEPENDS+= +iw +wireless-regdb
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/compat/compat.ko \
|
||||
$(PKG_BUILD_DIR)/net/wireless/cfg80211.ko
|
||||
|
@ -1516,7 +1516,6 @@ config-y:= \
|
|||
WLAN \
|
||||
NL80211_TESTMODE \
|
||||
CFG80211_WEXT \
|
||||
CFG80211_INTERNAL_REGDB \
|
||||
CFG80211_CERTIFICATION_ONUS \
|
||||
MAC80211_RC_MINSTREL \
|
||||
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,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_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED
|
||||
|
||||
|
@ -1742,7 +1741,6 @@ define Build/Prepare
|
|||
$(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
+++ b/compat/Makefile
|
||||
@@ -39,8 +39,6 @@ compat-$(CPTCFG_KERNEL_4_10) += backport
|
||||
|
||||
compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o
|
||||
compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o
|
||||
@@ -70,8 +70,6 @@ quiet_cmd_build_OID_registry = GEN $
|
||||
cmd_build_OID_registry = perl $(src)/build_OID_registry $< $@
|
||||
compat-$(CPTCFG_BPAUTO_ASN1_DECODER) += lib-asn1_decoder.o
|
||||
compat-$(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION) += lib-oid_registry.o
|
||||
-skcipher-objs += crypto-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
|
||||
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
|
||||
+++ 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.
|
||||
|
||||
config LIB80211
|
||||
|
@ -9,7 +9,7 @@
|
|||
depends on m
|
||||
default n
|
||||
help
|
||||
@@ -181,15 +181,15 @@ config LIB80211
|
||||
@@ -191,15 +191,15 @@ config LIB80211
|
||||
Drivers should select this themselves if needed.
|
||||
|
||||
config LIB80211_CRYPT_WEP
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -383,45 +383,6 @@ USB_IPHETH=
|
||||
@@ -388,45 +388,6 @@ USB_IPHETH=
|
||||
USB_SIERRA_NET=
|
||||
USB_VL600=
|
||||
USB_NET_CH9200=
|
||||
|
@ -121,7 +121,7 @@
|
|||
#source "$BACKPORT_DIR/drivers/media/Kconfig"
|
||||
--- a/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_BT) += net/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
|
||||
+++ 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 \
|
||||
tkip.o \
|
||||
aes_ccm.o \
|
||||
- aes_gcm.o \
|
||||
+ aes_ccm.o \
|
||||
aes_cmac.o \
|
||||
- aes_gmac.o \
|
||||
fils_aead.o \
|
||||
cfg.o \
|
||||
ethtool.o \
|
||||
--- a/net/mac80211/aes_ccm.c
|
||||
+++ b/net/mac80211/aes_ccm.c
|
||||
@@ -13,103 +13,132 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/err.h>
|
||||
#include <crypto/aead.h>
|
||||
+#include <crypto/aes.h>
|
||||
|
||||
#include <net/mac80211.h>
|
||||
#include "key.h"
|
||||
#include "aes_ccm.h"
|
||||
|
||||
-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
||||
- 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,
|
||||
+ u8 *a, u8 *b)
|
||||
{
|
||||
--- a/net/mac80211/aead_api.c
|
||||
+++ /dev/null
|
||||
@@ -1,115 +0,0 @@
|
||||
-/*
|
||||
- * Copyright 2003-2004, Instant802 Networks, Inc.
|
||||
- * Copyright 2005-2006, Devicescape Software, Inc.
|
||||
- * Copyright 2014-2015, Qualcomm Atheros, Inc.
|
||||
- *
|
||||
- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
|
||||
- *
|
||||
- * 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 <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 aead_request *aead_req;
|
||||
- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
- u8 *__aad;
|
||||
+ int i;
|
||||
|
||||
- aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
|
||||
-
|
||||
- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
|
||||
- if (!aead_req)
|
||||
- return -ENOMEM;
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b_0);
|
||||
|
||||
-
|
||||
- __aad = (u8 *)aead_req + reqsize;
|
||||
- memcpy(__aad, aad, CCM_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);
|
||||
|
||||
- memcpy(__aad, aad, aad_len);
|
||||
-
|
||||
- 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[2], mic, mic_len);
|
||||
+ aad += AES_BLOCK_SIZE;
|
||||
|
||||
-
|
||||
- aead_request_set_tfm(aead_req, tfm);
|
||||
- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
|
||||
- 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);
|
||||
- kzfree(aead_req);
|
||||
+ /* Mask out bits from auth-only-b_0 */
|
||||
+ b_0[0] &= 0x07;
|
||||
|
||||
-
|
||||
- return 0;
|
||||
+ /* 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);
|
||||
}
|
||||
|
||||
-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)
|
||||
{
|
||||
-}
|
||||
-
|
||||
-int aead_decrypt(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 aead_request *aead_req;
|
||||
- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
- u8 *__aad;
|
||||
- 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)
|
||||
- return -EINVAL;
|
||||
+ 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);
|
||||
|
||||
- aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
|
||||
-
|
||||
- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
|
||||
- if (!aead_req)
|
||||
- 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;
|
||||
- memcpy(__aad, aad, CCM_AAD_LEN);
|
||||
+ /* Authentication followed by encryption */
|
||||
+ for (i = 0; i < blen; i++)
|
||||
+ b[i] ^= pos[i];
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b);
|
||||
|
||||
- memcpy(__aad, aad, aad_len);
|
||||
-
|
||||
- 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[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_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
|
||||
- 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);
|
||||
- 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;
|
||||
+ 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_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 *
|
||||
-aead_key_setup_encrypt(const char *alg, const u8 key[],
|
||||
- size_t key_len, size_t mic_len)
|
||||
-{
|
||||
- struct crypto_aead *tfm;
|
||||
- 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))
|
||||
- return tfm;
|
||||
+ struct crypto_cipher *tfm;
|
||||
|
||||
-
|
||||
- err = crypto_aead_setkey(tfm, key, key_len);
|
||||
- if (err)
|
||||
- goto free_aead;
|
||||
- err = crypto_aead_setauthsize(tfm, mic_len);
|
||||
- if (err)
|
||||
- goto free_aead;
|
||||
+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
|
||||
+ if (!IS_ERR(tfm))
|
||||
+ crypto_cipher_setkey(tfm, key, key_len);
|
||||
|
||||
return tfm;
|
||||
-
|
||||
- return tfm;
|
||||
-
|
||||
-free_aead:
|
||||
- crypto_free_aead(tfm);
|
||||
- return ERR_PTR(err);
|
||||
}
|
||||
|
||||
-void ieee80211_aes_key_free(struct crypto_aead *tfm)
|
||||
+
|
||||
+void ieee80211_aes_key_free(struct crypto_cipher *tfm)
|
||||
{
|
||||
-}
|
||||
-
|
||||
-void aead_key_free(struct crypto_aead *tfm)
|
||||
-{
|
||||
- crypto_free_aead(tfm);
|
||||
+ crypto_free_cipher(tfm);
|
||||
}
|
||||
--- 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
|
||||
-}
|
||||
--- a/net/mac80211/aead_api.h
|
||||
+++ /dev/null
|
||||
@@ -1,27 +0,0 @@
|
||||
-/*
|
||||
- * 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.
|
||||
- */
|
||||
-
|
||||
-#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[],
|
||||
- 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 *
|
||||
+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
|
||||
-#include "aead_api.h"
|
||||
-
|
||||
-#define CCM_AAD_LEN 32
|
||||
-
|
||||
-static inline struct crypto_aead *
|
||||
-ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_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
|
||||
+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
|
||||
+ const u8 *data, size_t data_len, u8 *mic)
|
||||
+int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ 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
|
||||
+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 */
|
||||
--- 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 {
|
||||
-static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm,
|
||||
- u8 *j_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
+static inline int
|
||||
+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
- return aead_decrypt(tfm, j_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
+ return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
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
|
||||
+++ b/net/mac80211/wpa.c
|
||||
@@ -306,7 +306,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
|
||||
|
@ -318,7 +436,7 @@
|
|||
pos += IEEE80211_CCMP_HDR_LEN;
|
||||
- ccmp_special_blocks(skb, pn, b_0, aad);
|
||||
- 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);
|
||||
+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, 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 b_0[AES_BLOCK_SIZE];
|
||||
/* hardware didn't decrypt/verify MIC */
|
||||
|
@ -336,6 +454,13 @@
|
|||
|
||||
if (ieee80211_aes_ccm_decrypt(
|
||||
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
|
||||
u8 *pos;
|
||||
u8 pn[6];
|
||||
|
@ -379,70 +504,202 @@
|
|||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
||||
if (!ieee80211_is_mgmt(hdr->frame_control))
|
||||
--- a/net/mac80211/aes_ccm.h
|
||||
+++ b/net/mac80211/aes_ccm.h
|
||||
@@ -12,17 +12,15 @@
|
||||
|
||||
#include <linux/crypto.h>
|
||||
|
||||
-#define CCM_AAD_LEN 32
|
||||
-
|
||||
-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
|
||||
- size_t key_len,
|
||||
- size_t mic_len);
|
||||
-int ieee80211_aes_ccm_encrypt(struct crypto_aead *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_aead *tfm, u8 *b_0, u8 *aad,
|
||||
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
|
||||
+ size_t key_len,
|
||||
+ size_t mic_len);
|
||||
--- /dev/null
|
||||
+++ b/net/mac80211/aes_ccm.c
|
||||
@@ -0,0 +1,144 @@
|
||||
+/*
|
||||
+ * Copyright 2003-2004, Instant802 Networks, Inc.
|
||||
+ * Copyright 2005-2006, Devicescape Software, Inc.
|
||||
+ *
|
||||
+ * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
|
||||
+ *
|
||||
+ * 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 <crypto/aes.h>
|
||||
+
|
||||
+#include <net/mac80211.h>
|
||||
+#include "key.h"
|
||||
+#include "aes_ccm.h"
|
||||
+
|
||||
+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
|
||||
+ u8 *a, u8 *b)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b_0);
|
||||
+
|
||||
+ /* 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);
|
||||
+
|
||||
+ aad += AES_BLOCK_SIZE;
|
||||
+
|
||||
+ for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
+ aad[i] ^= b[i];
|
||||
+ 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);
|
||||
+ 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);
|
||||
-void ieee80211_aes_key_free(struct crypto_aead *tfm);
|
||||
+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
|
||||
|
||||
#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)
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len)
|
||||
+{
|
||||
+}
|
||||
|
||||
-int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
- u8 *data, size_t data_len, u8 *mic);
|
||||
-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
- u8 *data, size_t data_len, u8 *mic);
|
||||
-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
|
||||
- size_t key_len);
|
||||
-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
|
||||
+static inline int
|
||||
+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+ 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 *
|
||||
+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
|
||||
+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
|
||||
+++ 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;
|
||||
|
||||
__sta_info_flush(sdata, true);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
static int ieee80211_ifa6_changed(struct notifier_block *nb,
|
||||
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)
|
||||
goto fail_flows;
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
|
||||
result = register_inet6addr_notifier(&local->ifa6_notifier);
|
||||
if (result)
|
||||
@@ -1131,13 +1131,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
@@ -1130,13 +1130,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
|||
fail_ifa:
|
||||
#endif
|
||||
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->tasklet);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/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
|
||||
* lost)
|
||||
*/
|
||||
|
|
|
@ -48,7 +48,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
|||
if (likely(sta)) {
|
||||
if (!IS_ERR(sta))
|
||||
tx->sta = sta;
|
||||
@@ -3434,6 +3434,7 @@ begin:
|
||||
@@ -3468,6 +3468,7 @@ begin:
|
||||
tx.local = local;
|
||||
tx.skb = skb;
|
||||
tx.sdata = vif_to_sdata(info->control.vif);
|
||||
|
@ -56,7 +56,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
|||
|
||||
if (txq->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;
|
||||
tx.sta = sta_info_get(sdata, hdr->addr1);
|
||||
tx.skb = skb;
|
||||
|
|
|
@ -23,9 +23,9 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
|||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -2056,6 +2056,9 @@ struct ieee80211_txq {
|
||||
* The stack will not do fragmentation.
|
||||
* The callback for @set_frag_threshold should be set as well.
|
||||
@@ -2059,6 +2059,9 @@ struct ieee80211_txq {
|
||||
* @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on
|
||||
* TDLS links.
|
||||
*
|
||||
+ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte.
|
||||
+ * 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
|
||||
*/
|
||||
enum ieee80211_hw_flags {
|
||||
@@ -2098,6 +2101,7 @@ enum ieee80211_hw_flags {
|
||||
IEEE80211_HW_TX_FRAG_LIST,
|
||||
@@ -2102,6 +2105,7 @@ enum ieee80211_hw_flags {
|
||||
IEEE80211_HW_REPORTS_LOW_ACK,
|
||||
IEEE80211_HW_SUPPORTS_TX_FRAG,
|
||||
IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
|
||||
+ IEEE80211_HW_NEEDS_ALIGNED4_SKBS,
|
||||
|
||||
/* keep last, obviously */
|
||||
NUM_IEEE80211_HW_FLAGS
|
||||
--- a/net/mac80211/debugfs.c
|
||||
+++ b/net/mac80211/debugfs.c
|
||||
@@ -211,6 +211,7 @@ static const char *hw_flag_names[] = {
|
||||
FLAG(TX_FRAG_LIST),
|
||||
@@ -212,6 +212,7 @@ static const char *hw_flag_names[] = {
|
||||
FLAG(REPORTS_LOW_ACK),
|
||||
FLAG(SUPPORTS_TX_FRAG),
|
||||
FLAG(SUPPORTS_TDLS_BUFFER_STA),
|
||||
+ FLAG(NEEDS_ALIGNED4_SKBS),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
--- a/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;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
|||
unsigned int mpdu_len,
|
||||
--- a/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 sa_offs, da_offs, pn_offs;
|
||||
u8 band;
|
||||
|
@ -147,7 +147,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
|||
|
||||
if (likely(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;
|
||||
|
||||
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)
|
||||
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_sub_if_data *ap_sdata;
|
||||
enum nl80211_band band;
|
||||
|
@ -165,7 +165,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
|||
|
||||
if (IS_ERR(sta))
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
|||
/*
|
||||
* Drop unicast frames to unauthorised stations unless they are
|
||||
* 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);
|
||||
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
|
||||
@@ -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);
|
||||
#endif
|
||||
|
||||
|
@ -193,7 +193,7 @@ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
|
|||
if (ieee80211_is_data_qos(fc)) {
|
||||
__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);
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
* 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,
|
||||
@@ -3461,7 +3470,7 @@ begin:
|
||||
@@ -3495,7 +3504,7 @@ begin:
|
||||
|
||||
if (tx.key &&
|
||||
(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
|
||||
+++ 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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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---
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -82,6 +82,7 @@ ADM8211=
|
||||
@@ -87,6 +87,7 @@ ADM8211=
|
||||
ATH_COMMON=
|
||||
WLAN_VENDOR_ATH=
|
||||
ATH_DEBUG=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/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;
|
||||
struct regulatory_request *request = NULL, *lr;
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
|||
/* IE len must be evenly divisible by 2 */
|
||||
if (country_ie_len & 0x01)
|
||||
return;
|
||||
@@ -2703,6 +2705,7 @@ static void restore_regulatory_settings(
|
||||
@@ -3066,6 +3068,7 @@ static void restore_regulatory_settings(
|
||||
|
||||
void regulatory_hint_disconnect(void)
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
u8 ps_dtim_period;
|
||||
--- a/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_PORT_AUTHORIZED: (reserved)
|
||||
*
|
||||
|
@ -46,7 +46,7 @@
|
|||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__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_PORT_AUTHORIZED,
|
||||
|
||||
|
@ -57,7 +57,7 @@
|
|||
__NL80211_ATTR_AFTER_LAST,
|
||||
--- a/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;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@
|
|||
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
|
||||
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_tx_power = ieee80211_set_tx_power,
|
||||
.get_tx_power = ieee80211_get_tx_power,
|
||||
|
@ -87,7 +87,7 @@
|
|||
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
||||
--- a/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 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);
|
||||
--- a/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))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
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",
|
||||
chan->center_freq, chandef->width);
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
|||
+ }
|
||||
+
|
||||
/* 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);
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hsr.c
|
||||
|
@ -343,7 +343,7 @@
|
|||
|
||||
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)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
@ -351,7 +351,7 @@
|
|||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,7 @@
|
|||
#endif /* _LINUX_ATH9K_PLATFORM_H */
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -109,6 +109,7 @@ ATH9K_WOW=
|
||||
@@ -114,6 +114,7 @@ ATH9K_WOW=
|
||||
ATH9K_RFKILL=
|
||||
ATH9K_CHANNEL_CONTEXT=
|
||||
ATH9K_PCOEM=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -291,6 +291,7 @@ RT2X00_LIB_FIRMWARE=
|
||||
@@ -296,6 +296,7 @@ RT2X00_LIB_FIRMWARE=
|
||||
RT2X00_LIB_CRYPTO=
|
||||
RT2X00_LIB_LEDS=
|
||||
RT2X00_LIB_DEBUGFS=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/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;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
|||
err_wiphy_new:
|
||||
--- a/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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/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->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
|
||||
+++ 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;
|
||||
queue_work(ar->workqueue, &ar->register_work);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/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;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
int ath10k_mac_register(struct ath10k *ar)
|
||||
{
|
||||
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);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/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) {
|
||||
ath10k_err(ar, "could not execute otp for board id check: %d\n",
|
||||
ret);
|
||||
|
|
Loading…
Reference in a new issue